diff options
author | Rahul P | 2020-03-04 17:01:11 +0530 |
---|---|---|
committer | GitHub | 2020-03-04 17:01:11 +0530 |
commit | 8ffe81b36caa259151978de0434e4e0c5c32d217 (patch) | |
tree | 32202454d13dfabbf6556e98987f2a9632619ea9 /src/kicadtoNgspice | |
parent | e40317e709c220176fc5b7edf23d4434504335b0 (diff) | |
parent | 13f3bcfda9416624cebbf5705de398e8efcad344 (diff) | |
download | eSim-8ffe81b36caa259151978de0434e4e0c5c32d217.tar.gz eSim-8ffe81b36caa259151978de0434e4e0c5c32d217.tar.bz2 eSim-8ffe81b36caa259151978de0434e4e0c5c32d217.zip |
Merge pull request #132 from rahulp13/master
major changes
Diffstat (limited to 'src/kicadtoNgspice')
-rw-r--r-- | src/kicadtoNgspice/Analysis.py | 272 | ||||
-rw-r--r-- | src/kicadtoNgspice/Convert.py | 57 | ||||
-rw-r--r-- | src/kicadtoNgspice/DeviceModel.py | 130 | ||||
-rw-r--r-- | src/kicadtoNgspice/KicadtoNgspice.py | 679 | ||||
-rw-r--r-- | src/kicadtoNgspice/Model.py | 54 | ||||
-rw-r--r-- | src/kicadtoNgspice/Processing.py | 110 | ||||
-rw-r--r-- | src/kicadtoNgspice/Source.py | 133 | ||||
-rw-r--r-- | src/kicadtoNgspice/SubcircuitTab.py | 73 | ||||
-rw-r--r-- | src/kicadtoNgspice/TrackWidget.py | 10 |
9 files changed, 754 insertions, 764 deletions
diff --git a/src/kicadtoNgspice/Analysis.py b/src/kicadtoNgspice/Analysis.py index b24f24c7..da030153 100644 --- a/src/kicadtoNgspice/Analysis.py +++ b/src/kicadtoNgspice/Analysis.py @@ -1,29 +1,27 @@ - -from PyQt4 import QtGui +from PyQt4 import QtGui, QtCore from . import TrackWidget import os -# from xml.etree import ElementTree as ET -import json +from xml.etree import ElementTree as ET class Analysis(QtGui.QWidget): """ - This class create Analysis Tab in KicadtoNgspice Window. 4 sections - - - - Select Analysis Type - - - AC Analysis - - - DC Analysis - - - Transient Analysis - - Set various track widget options here, for tracking purposes across\ - different functions and modules - - - - AC_entry_var - - - AC_Parameter - - - DC_entry_var - - - DC_Parameter - - - TRAN_entry_var - - - TRAN_Parameter - - - set_Checkbox - - - AC_type - - - op_check + - Select Analysis Type + - AC Analysis + - DC Analysis + - Transient Analysis + - Set various track widget options here, for tracking purposes across \ + different functions and modules - + - AC_entry_var + - AC_Parameter + - DC_entry_var + - DC_Parameter + - TRAN_entry_var + - TRAN_Parameter + - set_Checkbox + - AC_type + - op_check """ def __init__(self, clarg1): @@ -42,19 +40,21 @@ class Analysis(QtGui.QWidget): def createAnalysisWidget(self): """ - - Create the main anaylsis widget overwiew - - - Checkbox for analysis type - - - Place, `AC`, `DC` and `TRANSIENT` analysis tab - - - `self.acbox`, `self.dcbox`,`self.trbox`... + - Create the main anaylsis widget overwiew: + - Checkbox for analysis type + - Place, `AC`, `DC` and `TRANSIENT` analysis tab + - `self.acbox`, `self.dcbox`, `self.trbox`... - Check for `analysis` file, if any in projDir, extract data from it - Else set the default checkbox to `TRAN` - Accordingly set state for track widget options, as `TRAN`, `AC` ... """ self.grid = QtGui.QGridLayout() - self.grid.addWidget(self.createCheckBox(), 0, 0) - self.grid.addWidget(self.createACgroup(), 1, 0) - self.grid.addWidget(self.createDCgroup(), 2, 0) - self.grid.addWidget(self.createTRANgroup(), 3, 0) + self.setLayout(self.grid) + + self.grid.addWidget(self.createCheckBox(), 0, 0, QtCore.Qt.AlignTop) + self.grid.addWidget(self.createACgroup(), 1, 0, 5, 0) + self.grid.addWidget(self.createDCgroup(), 1, 0, 5, 0) + self.grid.addWidget(self.createTRANgroup(), 1, 0, 5, 0) try: kicadFile = self.clarg1 @@ -74,6 +74,10 @@ class Analysis(QtGui.QWidget): self.acbox.setDisabled(False) self.dcbox.setDisabled(True) self.trbox.setDisabled(True) + + self.acbox.setVisible(True) + self.dcbox.setVisible(False) + self.trbox.setVisible(False) self.track_obj.set_CheckBox["ITEMS"] = "AC" if contentlist[1] == 'lin': self.Lin.setChecked(True) @@ -90,6 +94,10 @@ class Analysis(QtGui.QWidget): self.dcbox.setDisabled(False) self.acbox.setDisabled(True) self.trbox.setDisabled(True) + + self.dcbox.setVisible(True) + self.acbox.setVisible(False) + self.trbox.setVisible(False) self.track_obj.set_CheckBox["ITEMS"] = "DC" elif contentlist[0] == '.tran': @@ -97,6 +105,10 @@ class Analysis(QtGui.QWidget): self.trbox.setDisabled(False) self.acbox.setDisabled(True) self.dcbox.setDisabled(True) + + self.trbox.setVisible(True) + self.dcbox.setVisible(False) + self.acbox.setVisible(False) self.track_obj.set_CheckBox["ITEMS"] = "TRAN" elif contentlist[0] == '.op': @@ -104,6 +116,10 @@ class Analysis(QtGui.QWidget): self.dcbox.setDisabled(False) self.acbox.setDisabled(True) self.trbox.setDisabled(True) + + self.dcbox.setVisible(True) + self.acbox.setVisible(False) + self.trbox.setVisible(False) self.check.setChecked(True) self.track_obj.set_CheckBox["ITEMS"] = "DC" @@ -111,7 +127,6 @@ class Analysis(QtGui.QWidget): self.checkTRAN.setChecked(True) self.track_obj.set_CheckBox["ITEMS"] = "TRAN" - self.setLayout(self.grid) self.show() def createCheckBox(self): @@ -151,27 +166,39 @@ class Analysis(QtGui.QWidget): self.acbox.setDisabled(False) self.dcbox.setDisabled(True) self.trbox.setDisabled(True) + + self.acbox.setVisible(True) + self.dcbox.setVisible(False) + self.trbox.setVisible(False) self.track_obj.set_CheckBox["ITEMS"] = "AC" elif self.checkDC.isChecked(): self.dcbox.setDisabled(False) self.acbox.setDisabled(True) self.trbox.setDisabled(True) + + self.dcbox.setVisible(True) + self.acbox.setVisible(False) + self.trbox.setVisible(False) self.track_obj.set_CheckBox["ITEMS"] = "DC" elif self.checkTRAN.isChecked(): self.trbox.setDisabled(False) self.acbox.setDisabled(True) self.dcbox.setDisabled(True) + + self.trbox.setVisible(True) + self.acbox.setVisible(False) + self.dcbox.setVisible(False) self.track_obj.set_CheckBox["ITEMS"] = "TRAN" def createACgroup(self): """ - Designing of AC group in analysis tab - 3 radio buttons - Lin | Dec | Oct - - 3 input boxes, with top 2 combos\ + - 3 input boxes, with top 2 combos - If previous values exist then fill default values from - previous value json file + previous value xml file """ kicadFile = self.clarg1 (projpath, filename) = os.path.split(kicadFile) @@ -183,17 +210,21 @@ class Analysis(QtGui.QWidget): os.path.join( projpath, project_name + - "_Previous_Values.json"), + "_Previous_Values.xml"), 'r') - data = f.read() - json_data = json.loads(data) + tree = ET.parse(f) + parent_root = tree.getroot() + for child in parent_root: + if child.tag == "analysis": + root = child except BaseException: check = 0 - print("AC Previous Values JSON is Empty") + print("AC Previous Values XML is Empty") self.acbox = QtGui.QGroupBox() self.acbox.setTitle("AC Analysis") self.acbox.setDisabled(True) + self.acbox.setVisible(False) self.acgrid = QtGui.QGridLayout() self.radiobuttongroup = QtGui.QButtonGroup() self.Lin = QtGui.QRadioButton("Lin") @@ -246,8 +277,7 @@ class Analysis(QtGui.QWidget): # Try setting to default value from anaylsis file try: - self.ac_parameter[self.parameter_cnt] = str( - json_data["analysis"]["ac"]["Start Fre Combo"]) + self.ac_parameter[self.parameter_cnt] = str(root[0][6].text) except BaseException: self.ac_parameter[self.parameter_cnt] = "Hz" @@ -266,8 +296,7 @@ class Analysis(QtGui.QWidget): self.ac_parameter[1] = "Hz" try: - self.ac_parameter[self.parameter_cnt] = str( - json_data["analysis"]["ac"]["Stop Fre Combo"]) + self.ac_parameter[self.parameter_cnt] = str(root[0][7].text) except BaseException: self.ac_parameter[self.parameter_cnt] = "Hz" @@ -285,46 +314,38 @@ class Analysis(QtGui.QWidget): ") if check: try: - if json_data["analysis"]["ac"]["Lin"] == "true": + if root[0][0].text == "true": self.Lin.setChecked(True) self.Dec.setChecked(False) self.Oct.setChecked(False) - elif json_data["analysis"]["ac"]["Dec"] == "true": + elif root[0][1].text == "true": self.Lin.setChecked(False) self.Dec.setChecked(True) self.Oct.setChecked(False) - elif json_data["analysis"]["ac"]["Oct"] == "true": + elif root[0][2].text == "true": self.Lin.setChecked(False) self.Dec.setChecked(False) self.Oct.setChecked(True) - else: - pass - - self.ac_entry_var[0].setText( - json_data["analysis"]["ac"]["Start Frequency"]) - self.ac_entry_var[1].setText( - json_data["analysis"]["ac"]["Stop Frequency"]) - self.ac_entry_var[2].setText( - json_data["analysis"]["ac"]["No. of points"]) - index = self.start_fre_combo.findText( - json_data["analysis"]["ac"]["Start Fre Combo"]) + + self.ac_entry_var[0].setText(root[0][3].text) + self.ac_entry_var[1].setText(root[0][4].text) + self.ac_entry_var[2].setText(root[0][5].text) + index = self.start_fre_combo.findText(root[0][6].text) self.start_fre_combo.setCurrentIndex(index) - index = self.stop_fre_combo.findText( - json_data["analysis"]["ac"]["Stop Fre Combo"]) + index = self.stop_fre_combo.findText(root[0][7].text) self.stop_fre_combo.setCurrentIndex(index) except BaseException: - print("AC Analysis JSON Parse Error") + print("AC Analysis XML Parse Error") return self.acbox ''' - Below 2 functions handle combo value event listeners for - - - start frequency for ac - - - stop frequency for ac + - start frequency for ac + - stop frequency for ac - And accordingly set the ac_parameters ''' - def start_combovalue(self, text): """ - Handle start_fre_combo box event @@ -343,7 +364,7 @@ class Analysis(QtGui.QWidget): def set_ac_type(self): """ - - Set track object for AC, according to the type of radio box selected + Sets track object for AC, according to the type of radio box selected. """ self.parameter_cnt = 0 @@ -353,17 +374,15 @@ class Analysis(QtGui.QWidget): self.track_obj.AC_type["ITEMS"] = "dec" elif self.Oct.isChecked(): self.track_obj.AC_type["ITEMS"] = "oct" - else: - pass def createDCgroup(self): """ - Create DC area under analysis tab - Source 1 and 2, each having 4 input boxes as follows - - - Source - - - Start - - - Increment - - - Stop + - Source + - Start + - Increment + - Stop - The last 3 have combo box pertaining to their unit as well - Also in the end a checkbox, for operating system point analysis """ @@ -377,17 +396,21 @@ class Analysis(QtGui.QWidget): os.path.join( projpath, project_name + - "_Previous_Values.json"), + "_Previous_Values.xml"), 'r') - data = f.read() - json_data = json.loads(data) + tree = ET.parse(f) + parent_root = tree.getroot() + for child in parent_root: + if child.tag == "analysis": + root = child except BaseException: check = 0 - print("DC Previous Values JSON is empty") + print("DC Previous Values XML is empty") self.dcbox = QtGui.QGroupBox() self.dcbox.setTitle("DC Analysis") self.dcbox.setDisabled(True) + self.dcbox.setVisible(False) self.dcgrid = QtGui.QGridLayout() self.dcbox.setLayout(self.dcgrid) @@ -471,8 +494,7 @@ class Analysis(QtGui.QWidget): self.dcgrid.addWidget(self.start_combo, 2, 2) try: - self.dc_parameter[self.parameter_cnt] = str( - json_data["analysis"]["dc"]["Start Combo"]) + self.dc_parameter[self.parameter_cnt] = str(root[1][5].text) except BaseException: self.dc_parameter[self.parameter_cnt] = "Volts or Amperes" @@ -489,8 +511,7 @@ class Analysis(QtGui.QWidget): self.dcgrid.addWidget(self.increment_combo, 3, 2) try: - self.dc_parameter[self.parameter_cnt] = str( - json_data["analysis"]["dc"]["Increment Combo"]) + self.dc_parameter[self.parameter_cnt] = str(root[1][6].text) except BaseException: self.dc_parameter[self.parameter_cnt] = "Volts or Amperes" @@ -507,8 +528,7 @@ class Analysis(QtGui.QWidget): self.dcgrid.addWidget(self.stop_combo, 4, 2) try: - self.dc_parameter[self.parameter_cnt] = str( - json_data["analysis"]["dc"]["Stop Combo"]) + self.dc_parameter[self.parameter_cnt] = str(root[1][7].text) except BaseException: self.dc_parameter[self.parameter_cnt] = "Volts or Amperes" @@ -525,8 +545,7 @@ class Analysis(QtGui.QWidget): self.dcgrid.addWidget(self.start_combo2, 6, 2) try: - self.dc_parameter[self.parameter_cnt] = str( - json_data["analysis"]["dc"]["Start Combo2"]) + self.dc_parameter[self.parameter_cnt] = str(root[1][12].text) except BaseException: self.dc_parameter[self.parameter_cnt] = "Volts or Amperes" @@ -543,8 +562,7 @@ class Analysis(QtGui.QWidget): self.dcgrid.addWidget(self.increment_combo2, 7, 2) try: - self.dc_parameter[self.parameter_cnt] = str( - json_data["analysis"]["dc"]["Increment Combo2"]) + self.dc_parameter[self.parameter_cnt] = str(root[1][13].text) except BaseException: self.dc_parameter[self.parameter_cnt] = "Volts or Amperes" @@ -562,8 +580,7 @@ class Analysis(QtGui.QWidget): self.dcgrid.addWidget(self.stop_combo2, 8, 2) try: - self.dc_parameter[self.parameter_cnt] = str( - json_data["analysis"]["dc"]["Stop Combo2"]) + self.dc_parameter[self.parameter_cnt] = str(root[1][14].text) except BaseException: self.dc_parameter[self.parameter_cnt] = "Volts or Amperes" @@ -573,7 +590,7 @@ class Analysis(QtGui.QWidget): self.check = QtGui.QCheckBox('Operating Point Analysis', self) try: self.track_obj.op_check.append( - str(json_data["analysis"]["dc"]["Operating Point"])) + str(root[1][4].text())) except BaseException: self.track_obj.op_check.append('0') @@ -595,47 +612,33 @@ class Analysis(QtGui.QWidget): ") if check: try: - self.dc_entry_var[0].setText( - json_data["analysis"]["dc"]["Source 1"]) - self.dc_entry_var[1].setText( - json_data["analysis"]["dc"]["Start"]) - self.dc_entry_var[2].setText( - json_data["analysis"]["dc"]["Increment"]) - self.dc_entry_var[3].setText( - json_data["analysis"]["dc"]["Stop"]) - index = self.start_combo.findText( - json_data["analysis"]["dc"]["Start Combo"]) + self.dc_entry_var[0].setText(root[1][0].text) + self.dc_entry_var[1].setText(root[1][1].text) + self.dc_entry_var[2].setText(root[1][2].text) + self.dc_entry_var[3].setText(root[1][3].text) + index = self.start_combo.findText(root[1][5].text) self.start_combo.setCurrentIndex(index) - index = self.increment_combo.findText( - json_data["analysis"]["dc"]["Increment Combo"]) + index = self.increment_combo.findText(root[1][6].text) self.increment_combo.setCurrentIndex(index) - index = self.stop_combo.findText( - json_data["analysis"]["dc"]["Stop Combo"]) + index = self.stop_combo.findText(root[1][7].text) self.stop_combo.setCurrentIndex(index) - self.dc_entry_var[4].setText( - json_data["analysis"]["dc"]["Source 2"]) - self.dc_entry_var[5].setText( - json_data["analysis"]["dc"]["Start2"]) - self.dc_entry_var[6].setText( - json_data["analysis"]["dc"]["Increment2"]) - self.dc_entry_var[7].setText( - json_data["analysis"]["dc"]["Stop2"]) - index = self.start_combo2.findText( - json_data["analysis"]["dc"]["Start Combo2"]) + self.dc_entry_var[4].setText(root[1][8].text) + self.dc_entry_var[5].setText(root[1][9].text) + self.dc_entry_var[6].setText(root[1][10].text) + self.dc_entry_var[7].setText(root[1][11].text) + index = self.start_combo2.findText(root[1][12].text) self.start_combo2.setCurrentIndex(index) - index = self.increment_combo2.findText( - json_data["analysis"]["dc"]["Increment Combo2"]) + index = self.increment_combo2.findText(root[1][13].text) self.increment_combo2.setCurrentIndex(index) - index = self.stop_combo2.findText( - json_data["analysis"]["dc"]["Stop Combo2"]) + index = self.stop_combo2.findText(root[1][14].text) self.stop_combo2.setCurrentIndex(index) - if json_data["analysis"]["dc"]["Operating Point"] == 1: + if root[1][4].text == 1: self.check.setChecked(True) else: self.check.setChecked(False) except BaseException: - print("DC Analysis JSON Parse Error") + print("DC Analysis XML Parse Error") return self.dcbox @@ -693,17 +696,21 @@ class Analysis(QtGui.QWidget): os.path.join( projpath, project_name + - "_Previous_Values.json"), + "_Previous_Values.xml"), 'r') - data = f.read() - json_data = json.loads(data) + tree = ET.parse(f) + parent_root = tree.getroot() + for child in parent_root: + if child.tag == "analysis": + root = child except BaseException: check = 0 - print("Transient Previous Values JSON is Empty") + print("Transient Previous Values XML is Empty") self.trbox = QtGui.QGroupBox() self.trbox.setTitle("Transient Analysis") # self.trbox.setDisabled(True) + # self.trbox.setVisible(False) self.trgrid = QtGui.QGridLayout() self.trbox.setLayout(self.trgrid) @@ -719,12 +726,10 @@ class Analysis(QtGui.QWidget): self.trgrid.addWidget(self.tran_entry_var[self.count], 1, 1) self.tran_entry_var[self.count].setMaximumWidth(150) self.count += 1 - self.tran_entry_var[self.count] = QtGui.QLineEdit() self.trgrid.addWidget(self.tran_entry_var[self.count], 2, 1) self.tran_entry_var[self.count].setMaximumWidth(150) self.count += 1 - self.tran_entry_var[self.count] = QtGui.QLineEdit() self.trgrid.addWidget(self.tran_entry_var[self.count], 3, 1) self.tran_entry_var[self.count].setMaximumWidth(150) @@ -740,8 +745,7 @@ class Analysis(QtGui.QWidget): self.trgrid.addWidget(self.start_combobox, 1, 3) try: - self.tran_parameter[self.parameter_cnt] = str( - json_data["analysis"]["tran"]["Start Combo"]) + self.tran_parameter[self.parameter_cnt] = str(root[2][3].text) except BaseException: self.tran_parameter[self.parameter_cnt] = "Sec" @@ -756,8 +760,7 @@ class Analysis(QtGui.QWidget): self.step_combobox.addItem("ps") self.trgrid.addWidget(self.step_combobox, 2, 3) try: - self.tran_parameter[self.parameter_cnt] = str( - json_data["analysis"]["tran"]["Step Combo"]) + self.tran_parameter[self.parameter_cnt] = str(root[2][4].text) except BaseException: self.tran_parameter[self.parameter_cnt] = "Sec" @@ -772,8 +775,7 @@ class Analysis(QtGui.QWidget): self.stop_combobox.addItem("ps") self.trgrid.addWidget(self.stop_combobox, 3, 3) try: - self.tran_parameter[self.parameter_cnt] = str( - json_data["analysis"]["tran"]["Stop Combo"]) + self.tran_parameter[self.parameter_cnt] = str(root[2][5].text) except BaseException: self.tran_parameter[self.parameter_cnt] = "Sec" @@ -792,29 +794,23 @@ class Analysis(QtGui.QWidget): ") if check: try: - self.tran_entry_var[0].setText( - json_data["analysis"]["tran"]["Start Time"]) - self.tran_entry_var[1].setText( - json_data["analysis"]["tran"]["Step Time"]) - self.tran_entry_var[2].setText( - json_data["analysis"]["tran"]["Stop Time"]) - index = self.start_combobox.findText( - json_data["analysis"]["tran"]["Start Combo"]) + self.tran_entry_var[0].setText(root[2][0].text) + self.tran_entry_var[1].setText(root[2][1].text) + self.tran_entry_var[2].setText(root[2][2].text) + index = self.start_combobox.findText(root[2][3].text) self.start_combobox.setCurrentIndex(index) - index = self.step_combobox.findText( - json_data["analysis"]["tran"]["Step Combo"]) + index = self.step_combobox.findText(root[2][4].text) self.step_combobox.setCurrentIndex(index) - index = self.stop_combobox.findText( - json_data["analysis"]["tran"]["Stop Combo"]) + index = self.stop_combobox.findText(root[2][5].text) self.stop_combobox.setCurrentIndex(index) except BaseException: - print("Transient Analysis JSON Parse Error") + print("Transient Analysis XML Parse Error") return self.trbox + ''' - Below 3 functions handle event for the combo box in transient group ''' - def start_combo_change(self, text): """Handle start combo box, ie. units, as second, ms""" self.tran_parameter[0] = str(text) diff --git a/src/kicadtoNgspice/Convert.py b/src/kicadtoNgspice/Convert.py index 883ba534..7ab57427 100644 --- a/src/kicadtoNgspice/Convert.py +++ b/src/kicadtoNgspice/Convert.py @@ -1,5 +1,4 @@ from PyQt4 import QtGui - import os import shutil from . import TrackWidget @@ -9,15 +8,15 @@ from xml.etree import ElementTree as ET class Convert: """ - This class has all the necessary function required to convert \ - kicad netlist to ngspice netlist. + kicad netlist to ngspice netlist. - Method List - - - addDeviceLibrary - - - addModelParameter - - - addSourceParameter - - - addSubcircuit - - - analysisInsertor - - - converttosciform - - - defaultvalue + - addDeviceLibrary + - addModelParameter + - addSourceParameter + - addSubcircuit + - analysisInsertor + - converttosciform + - defaultvalue """ def __init__(self, sourcelisttrack, source_entry_var, @@ -32,12 +31,12 @@ class Convert: """ - This function extracts the source details to schematicInfo - keywords recognised and parsed - - - - sine - - - pulse - - - pwl - - - ac - - - dc - - - exp + - sine + - pulse + - pwl + - ac + - dc + - exp - Return updated schematic """ @@ -355,7 +354,7 @@ class Convert: def addModelParameter(self, schematicInfo): """ - This function add the Ngspice Model details to schematicInfo + This function adds the Ngspice Model details to schematicInfo """ # Create object of TrackWidget @@ -446,8 +445,6 @@ class Convert: # end = line[8] addmodelLine = ".model " + line[3] + " " + line[2] + "(" for key, value in line[9].items(): - # print "Tags: ",key - # print "Value: ",value # Checking for default value and accordingly assign # param and default. if ':' in key: @@ -457,7 +454,7 @@ class Convert: else: param = key default = 0 - # Cheking if value is iterable.its for vector + # Checking if value is iterable.its for vector if ( not isinstance(value, str) and hasattr(value, '__iter__') @@ -516,17 +513,16 @@ class Convert: includeLine = [] # All .include line list if not deviceLibList: - print("No Library Added in the schematic") - pass + print("No library added in the schematic") else: for eachline in schematicInfo: words = eachline.split() if words[0] in deviceLibList: - print("Found Library line") + # print("Found Library line") index = schematicInfo.index(eachline) completeLibPath = deviceLibList[words[0]] (libpath, libname) = os.path.split(completeLibPath) - print("Library Path :", libpath) + # print("Library Path :", libpath) # Copying library from devicemodelLibrary to Project Path # Special case for MOSFET if eachline[0] == 'm': @@ -562,9 +558,6 @@ class Convert: dst = projpath shutil.copy2(src, dst) - else: - pass - # Adding device line to schematicInfo for index, value in deviceLine.items(): # Update the device line @@ -582,7 +575,6 @@ class Convert: """ This function add the subcircuit to schematicInfo """ - (projpath, filename) = os.path.split(kicadFile) subList = self.obj_track.subcircuitTrack @@ -593,14 +585,14 @@ class Convert: if len(self.obj_track.subcircuitList) != len( self.obj_track.subcircuitTrack): self.msg = QtGui.QErrorMessage() + self.msg.setModal(True) + self.msg.setWindowTitle("Error Message") self.msg.showMessage( "Conversion failed. Please add all Subcircuits.") - self.msg.setWindowTitle("Error Message") - self.msg.show() + self.msg.exec_() raise Exception('All subcircuit directories need to be specified.') elif not subList: print("No Subcircuit Added in the schematic") - pass else: for eachline in schematicInfo: words = eachline.split() @@ -624,8 +616,6 @@ class Convert: if os.path.isfile(os.path.join(src, files)): if files != "analysis": shutil.copy2(os.path.join(src, files), dst) - else: - pass # Adding subcircuit line to schematicInfo for index, value in subLine.items(): @@ -649,6 +639,5 @@ class Convert: for child in libtree.iter(): if child.tag == 'ref_model': retVal = child.text - else: - pass + return retVal diff --git a/src/kicadtoNgspice/DeviceModel.py b/src/kicadtoNgspice/DeviceModel.py index 7f63a43b..c4ea9a22 100644 --- a/src/kicadtoNgspice/DeviceModel.py +++ b/src/kicadtoNgspice/DeviceModel.py @@ -1,7 +1,6 @@ from PyQt4 import QtGui import os -# from xml.etree import ElementTree as ET -import json +from xml.etree import ElementTree as ET from . import TrackWidget @@ -12,13 +11,13 @@ class DeviceModel(QtGui.QWidget): transistor and jfet. - Same function as the subCircuit file, except for this takes different parameters in the if block - - - q TRANSISTOR - - - d DIODE - - - j JFET - - - m MOSFET + - q TRANSISTOR + - d DIODE + - j JFET + - m MOSFET - Other 2 functions same as the ones in subCircuit - - - trackLibrary - - - trackLibraryWithoutButton + - trackLibrary + - trackLibraryWithoutButton """ def __init__(self, schematicInfo, clarg1): @@ -33,12 +32,15 @@ class DeviceModel(QtGui.QWidget): os.path.join( projpath, project_name + - "_Previous_Values.json"), + "_Previous_Values.xml"), 'r') - data = f.read() - json_data = json.loads(data) + tree = ET.parse(f) + parent_root = tree.getroot() + for child in parent_root: + if child.tag == "devicemodel": + root = child except BaseException: - print("Device Model Previous JSON is Empty") + print("Device Model Previous XML is Empty") QtGui.QWidget.__init__(self) @@ -62,14 +64,14 @@ class DeviceModel(QtGui.QWidget): # Set Layout self.grid = QtGui.QGridLayout() self.setLayout(self.grid) - print("Reading Device model details from Schematic") + # print("Reading Device model details from Schematic") for eachline in schematicInfo: print("=========================================") print(eachline) words = eachline.split() if eachline[0] == 'q': - print("Device Model Transistor: ", words[0]) + # print("Device Model Transistor: ", words[0]) self.devicemodel_dict_beg[words[0]] = self.count transbox = QtGui.QGroupBox() transgrid = QtGui.QGridLayout() @@ -83,18 +85,15 @@ class DeviceModel(QtGui.QWidget): global path_name try: - for key in json_data["deviceModel"]: - if key == words[0]: - # print "DEVICE MODEL MATCHING---",child.tag[0],\ - # child.tag[1],eachline[0],eachline[1] + for child in root: + if child.tag == words[0]: + # print("DEVICE MODEL MATCHING---", \ + # child.tag, words[0]) try: - if os.path.exists( - json_data["deviceModel"][key][0]): - self.entry_var[self.count].setText( - json_data["deviceModel"][key][0]) - path_name = ( - json_data["deviceModel"][key][0] - ) + if os.path.exists(child[0].text): + self.entry_var[self.count] \ + .setText(child[0].text) + path_name = child[0].text else: self.entry_var[self.count].setText("") except BaseException: @@ -128,7 +127,7 @@ class DeviceModel(QtGui.QWidget): self.grid.addWidget(transbox) - # Adding Device Details + # Adding Device Details # # Increment row and widget count self.row = self.row + 1 @@ -136,7 +135,7 @@ class DeviceModel(QtGui.QWidget): self.count = self.count + 1 elif eachline[0] == 'd': - print("Device Model Diode:", words[0]) + # print("Device Model Diode:", words[0]) self.devicemodel_dict_beg[words[0]] = self.count diodebox = QtGui.QGroupBox() diodegrid = QtGui.QGridLayout() @@ -149,18 +148,15 @@ class DeviceModel(QtGui.QWidget): self.entry_var[self.count].setText("") # global path_name try: - for key in json_data["deviceModel"]: - if key == words[0]: - # print "DEVICE MODEL MATCHING---",child.tag[0],\ - # child.tag[1],eachline[0],eachline[1] + for child in root: + if child.tag == words[0]: + # print("DEVICE MODEL MATCHING---", \ + # child.tag, words[0]) try: - if os.path.exists( - json_data["deviceModel"][key][0]): - path_name = ( - json_data["deviceModel"][key][0] - ) - self.entry_var[self.count].setText( - json_data["deviceModel"][key][0]) + if os.path.exists(child[0].text): + path_name = child[0].text + self.entry_var[self.count] \ + .setText(child[0].text) else: self.entry_var[self.count].setText("") except BaseException: @@ -193,7 +189,7 @@ class DeviceModel(QtGui.QWidget): self.grid.addWidget(diodebox) - # Adding Device Details + # Adding Device Details # # Increment row and widget count self.row = self.row + 1 @@ -201,7 +197,7 @@ class DeviceModel(QtGui.QWidget): self.count = self.count + 1 elif eachline[0] == 'j': - print("Device Model JFET:", words[0]) + # print("Device Model JFET:", words[0]) self.devicemodel_dict_beg[words[0]] = self.count jfetbox = QtGui.QGroupBox() jfetgrid = QtGui.QGridLayout() @@ -214,18 +210,15 @@ class DeviceModel(QtGui.QWidget): self.entry_var[self.count].setText("") # global path_name try: - for key in json_data["deviceModel"]: - if key == words[0]: - # print "DEVICE MODEL MATCHING---",child.tag[0],\ - # child.tag[1],eachline[0],eachline[1] + for child in root: + if child.tag == words[0]: + # print("DEVICE MODEL MATCHING---", \ + # child.tag, words[0]) try: - if os.path.exists( - json_data["deviceModel"][key][0]): - self.entry_var[self.count].setText( - json_data["deviceModel"][key][0]) - path_name = ( - json_data["deviceModel"][key][0] - ) + if os.path.exists(child[0].text): + self.entry_var[self.count] \ + .setText(child[0].text) + path_name = child[0].text else: self.entry_var[self.count].setText("") except BaseException: @@ -258,7 +251,8 @@ class DeviceModel(QtGui.QWidget): self.grid.addWidget(jfetbox) - # Adding Device Details + # Adding Device Details # + # Increment row and widget count self.row = self.row + 1 self.devicemodel_dict_end[words[0]] = self.count @@ -325,21 +319,20 @@ class DeviceModel(QtGui.QWidget): self.devicemodel_dict_end[words[0]] = self.count self.count = self.count + 1 mosfetbox.setLayout(mosfetgrid) + # global path_name try: - for key in json_data["deviceModel"]: - if key == words[0]: - # print "DEVICE MODEL MATCHING---",child.tag[0],\ - # child.tag[1],eachline[0],eachline[1] + for child in root: + if child.tag == words[0]: + # print("DEVICE MODEL MATCHING---", \ + # child.tag, words[0]) while i <= end: - self.entry_var[i].setText( - json_data["deviceModel"][key][i - beg]) + self.entry_var[i].setText(child[i-beg].text) if (i - beg) == 0: - if os.path.exists( - json_data["deviceModel"][key][0]): - path_name = ( - json_data["deviceModel"][key][0] - ) + if os.path.exists(child[0].text): + self.entry_var[i] \ + .setText(child[i-beg].text) + path_name = child[i-beg].text else: self.entry_var[i].setText("") i = i + 1 @@ -367,23 +360,19 @@ class DeviceModel(QtGui.QWidget): """ print("Calling Track Device Model Library funtion") sending_btn = self.sender() - # print "Object Called is ",sending_btn.objectName() self.widgetObjCount = int(sending_btn.objectName()) self.libfile = str( QtGui.QFileDialog.getOpenFileName( - self, - "Open Library Directory", - "../deviceModelLibrary", + self, "Open Library Directory", + "library/deviceModelLibrary", "*.lib")) - # print "Selected Library File :",self.libfile # Setting Library to Text Edit Line self.entry_var[self.widgetObjCount].setText(self.libfile) self.deviceName = self.deviceDetail[self.widgetObjCount] # Storing to track it during conversion - if self.deviceName[0] == 'm': width = str(self.entry_var[self.widgetObjCount + 1].text()) length = str(self.entry_var[self.widgetObjCount + 2].text()) @@ -406,19 +395,16 @@ class DeviceModel(QtGui.QWidget): This function is use to keep track of all Device Model widget """ print("Calling Track Library function Without Button") - # print "Object Called is ",sending_btn.objectName() self.widgetObjCount = iter_value print("self.widgetObjCount-----", self.widgetObjCount) self.libfile = path_value print("PATH VALUE", path_value) - # print "Selected Library File :",self.libfile # Setting Library to Text Edit Line self.entry_var[self.widgetObjCount].setText(self.libfile) self.deviceName = self.deviceDetail[self.widgetObjCount] # Storing to track it during conversion - if self.deviceName[0] == 'm': width = str(self.entry_var[self.widgetObjCount + 1].text()) length = str(self.entry_var[self.widgetObjCount + 2].text()) diff --git a/src/kicadtoNgspice/KicadtoNgspice.py b/src/kicadtoNgspice/KicadtoNgspice.py index ef9201cb..c1421829 100644 --- a/src/kicadtoNgspice/KicadtoNgspice.py +++ b/src/kicadtoNgspice/KicadtoNgspice.py @@ -1,5 +1,4 @@ # ========================================================================= -# # FILE: kicadtoNgspice.py # # USAGE: --- @@ -11,10 +10,12 @@ # BUGS: --- # NOTES: --- # AUTHOR: Fahim Khan, fahim.elex@gmail.com +# MODIFIED: Rahul Paknikar, rahulp@iitb.ac.in # ORGANIZATION: eSim team at FOSSEE, IIT Bombay. # CREATED: Wednesday 04 March 2015 -# REVISION: --- +# REVISION: Friday 14 February 2020 # ========================================================================= + import sys import os from PyQt4 import QtGui @@ -26,9 +27,7 @@ from . import DeviceModel from . import SubcircuitTab from . import Convert from . import TrackWidget -import json - -# from xml.etree import ElementTree as ET +from xml.etree import ElementTree as ET class MainWindow(QtGui.QWidget): @@ -37,7 +36,7 @@ class MainWindow(QtGui.QWidget): - And Call Convert function if convert button is pressed. - The convert function takes all the value entered by user and create a final netlist "*.cir.out". - - This final netlist is compatible with NgSpice. + - This final netlist is compatible with Ngspice. - clarg1 is the path to the .cir file - clarg2 is either None or "sub" depending on the analysis type """ @@ -45,7 +44,7 @@ class MainWindow(QtGui.QWidget): def __init__(self, clarg1, clarg2=None): QtGui.QWidget.__init__(self) print("==================================") - print("Kicad to Ngspice netlist converter ") + print("Kicad to Ngspice netlist converter") print("==================================") global kicadNetlist, schematicInfo global infoline, optionInfo @@ -54,10 +53,10 @@ class MainWindow(QtGui.QWidget): self.clarg2 = clarg2 # Create object of track widget - # Track the dynamically created widget of KicadtoNgSpice Window + # Track the dynamically created widget of KicadtoNgspice Window self.obj_track = TrackWidget.TrackWidget() - # Clear Dictionary/List item of sub circuit and ngspice model + # Clear Dictionary/List item of sub circuit and Ngspice model # Dictionary self.obj_track.subcircuitList.clear() self.obj_track.subcircuitTrack.clear() @@ -70,22 +69,21 @@ class MainWindow(QtGui.QWidget): # Read the netlist, ie the .cir file kicadNetlist = obj_proc.readNetlist(self.kicadFile) - print("=============================================================") - print("Given Kicad Schematic Netlist Info :", kicadNetlist) + # print("=============================================================") + # print("Given Kicad Schematic Netlist Info :", kicadNetlist) # Construct parameter information param = obj_proc.readParamInfo(kicadNetlist) # Replace parameter with values netlist, infoline = obj_proc.preprocessNetlist(kicadNetlist, param) - print("=============================================================") - print("Schematic Info after processing Kicad Netlist: ", netlist) - # print "INFOLINE",infoline + # print("=============================================================") + # print("Schematic Info after processing Kicad Netlist: ", netlist) # Separate option and schematic information optionInfo, schematicInfo = obj_proc.separateNetlistInfo(netlist) - print("=============================================================") - print("OPTIONINFO in the Netlist", optionInfo) + # print("=============================================================") + # print("OPTIONINFO in the Netlist", optionInfo) # List for storing source and its value global sourcelist, sourcelisttrack @@ -111,43 +109,47 @@ class MainWindow(QtGui.QWidget): ) = obj_proc.convertICintoBasicBlocks( schematicInfo, outputOption, modelList, plotText ) - print("=======================================") - print("Model available in the Schematic :", modelList) + # print("=======================================") + # print("Model available in the Schematic :", modelList) """ - Checking if any unknown model is used in schematic which is not - recognized by NgSpice. + recognized by Ngspice. - Also if the two model of same name is present under modelParamXML directory """ if unknownModelList: print("Unknown Model List is : ", unknownModelList) self.msg = QtGui.QErrorMessage() + self.msg.setModal(True) + self.msg.setWindowTitle("Unknown Models") self.content = "Your schematic contain unknown model " + \ ', '.join(unknownModelList) self.msg.showMessage(self.content) - self.msg.setWindowTitle("Unknown Models") + self.msg.exec_() elif multipleModelList: self.msg = QtGui.QErrorMessage() + self.msg.setModal(True) + self.msg.setWindowTitle("Multiple Models") self.mcontent = "Look like you have duplicate model in \ modelParamXML directory " + \ ', '.join(multipleModelList[0]) self.msg.showMessage(self.mcontent) - self.msg.setWindowTitle("Multiple Models") + self.msg.exec_() else: self.createMainWindow() def createMainWindow(self): """ - - This function create main window of Kicad to Ngspice converter + - This function create main window of KiCad to Ngspice converter - Two components - - - createcreateConvertWidget - - - Convert button => callConvert + - createcreateConvertWidget + - Convert button => callConvert """ - self.vbox = QtGui.QVBoxLayout(self) - self.hbox = QtGui.QHBoxLayout(self) + self.vbox = QtGui.QVBoxLayout() + self.hbox = QtGui.QHBoxLayout() self.hbox.addStretch(1) self.convertbtn = QtGui.QPushButton("Convert") self.convertbtn.clicked.connect(self.callConvert) @@ -162,23 +164,23 @@ class MainWindow(QtGui.QWidget): def createcreateConvertWidget(self): """ - Contains the tabs for various convertor elements - - - Analysis => obj_analysis + - Analysis => obj_analysis => Analysis.Analysis(`path_to_projFile`) - - - Source Details => obj_source + - Source Details => obj_source => Source.Source(`sourcelist`,`sourcelisttrack`,`path_to_projFile`) - - - NgSpice Model => obj_model + - NgSpice Model => obj_model => Model.Model(`schematicInfo`,`modelList`,`path_to_projFile`) - - - Device Modelling => obj_devicemodel + - Device Modelling => obj_devicemodel => DeviceModel.DeviceModel(`schematicInfo`,`path_to_projFile`) - - - Subcircuits => obj_subcircuitTab + - Subcircuits => obj_subcircuitTab => SubcircuitTab.SubcircuitTab(`schematicInfo`,`path_to_projFile`) - Finally pass each of these objects, to widgets - - convertWindow > mainLayout > tabWidgets > AnalysisTab, SourceTab .... + - convertWindow > mainLayout > tabWidgets > AnalysisTab, SourceTab ... """ global obj_analysis self.convertWindow = QtGui.QWidget() @@ -215,7 +217,7 @@ class MainWindow(QtGui.QWidget): # self.tabWidget.TabShape(QtGui.QTabWidget.Rounded) self.tabWidget.addTab(self.analysisTab, "Analysis") self.tabWidget.addTab(self.sourceTab, "Source Details") - self.tabWidget.addTab(self.modelTab, "NgSpice Model") + self.tabWidget.addTab(self.modelTab, "Ngspice Model") self.tabWidget.addTab(self.deviceModelTab, "Device Modeling") self.tabWidget.addTab(self.subcircuitTab, "Subcircuits") self.mainLayout = QtGui.QVBoxLayout() @@ -230,8 +232,8 @@ class MainWindow(QtGui.QWidget): """ - This function called when convert button clicked - Extracting data from the objs created above - - Pushing this data to json, and dumping it finally - - Written to a ..._Previous_Valuse.json file in the projDirectory + - Pushing this data to xml, and writing it finally + - Written to a ..._Previous_Values.xml file in the projDirectory - Finally, call createNetListFile, with the converted schematic """ global schematicInfo @@ -240,296 +242,361 @@ class MainWindow(QtGui.QWidget): store_schematicInfo = list(schematicInfo) (projpath, filename) = os.path.split(self.kicadFile) project_name = os.path.basename(projpath) + check = 1 + + try: + fr = open( + os.path.join( + projpath, project_name + "_Previous_Values.xml"), 'r' + ) + temp_tree = ET.parse(fr) + temp_root = temp_tree.getroot() + except BaseException: + check = 0 # Opening previous value file pertaining to the selected project - fw = open( - os.path.join( - projpath, - project_name + - "_Previous_Values.json"), - 'w') + fw = os.path.join(projpath, project_name + "_Previous_Values.xml") - # Creating a dictionary to map the json data - json_data = {} + if check == 0: + attr_parent = ET.Element("KicadtoNgspice") + if check == 1: + attr_parent = temp_root - # Writing analysis values - json_data["analysis"] = {} + for child in attr_parent: + if child.tag == "analysis": + attr_parent.remove(child) + + attr_analysis = ET.SubElement(attr_parent, "analysis") + attr_ac = ET.SubElement(attr_analysis, "ac") - json_data["analysis"]["ac"] = {} if obj_analysis.Lin.isChecked(): - json_data["analysis"]["ac"]["Lin"] = "true" - json_data["analysis"]["ac"]["Dec"] = "false" - json_data["analysis"]["ac"]["Oct"] = "false" + ET.SubElement(attr_ac, "field1", name="Lin").text = "true" + ET.SubElement(attr_ac, "field2", name="Dec").text = "false" + ET.SubElement(attr_ac, "field3", name="Oct").text = "false" elif obj_analysis.Dec.isChecked(): - json_data["analysis"]["ac"]["Lin"] = "false" - json_data["analysis"]["ac"]["Dec"] = "true" - json_data["analysis"]["ac"]["Oct"] = "false" + ET.SubElement(attr_ac, "field1", name="Lin").text = "false" + ET.SubElement(attr_ac, "field2", name="Dec").text = "true" + ET.SubElement(attr_ac, "field3", name="Oct").text = "false" if obj_analysis.Oct.isChecked(): - json_data["analysis"]["ac"]["Lin"] = "false" - json_data["analysis"]["ac"]["Dec"] = "false" - json_data["analysis"]["ac"]["Oct"] = "true" - else: - pass - - json_data["analysis"]["ac"]["Start Frequency"] = str( - obj_analysis.ac_entry_var[0].text()) - json_data["analysis"]["ac"]["Stop Frequency"] = str( - obj_analysis.ac_entry_var[1].text()) - json_data["analysis"]["ac"]["No. of points"] = str( - obj_analysis.ac_entry_var[2].text()) - json_data["analysis"]["ac"]["Start Fre Combo"] = ( - obj_analysis.ac_parameter[0] - ) - json_data["analysis"]["ac"]["Stop Fre Combo"] = ( - obj_analysis.ac_parameter[1] - ) - - json_data["analysis"]["dc"] = {} - json_data["analysis"]["dc"]["Source 1"] = str( - obj_analysis.dc_entry_var[0].text()) - json_data["analysis"]["dc"]["Start"] = str( - obj_analysis.dc_entry_var[1].text()) - json_data["analysis"]["dc"]["Increment"] = str( - obj_analysis.dc_entry_var[2].text()) - json_data["analysis"]["dc"]["Stop"] = str( - obj_analysis.dc_entry_var[3].text()) - json_data["analysis"]["dc"]["Operating Point"] = str( - self.obj_track.op_check[-1]) - json_data["analysis"]["dc"]["Start Combo"] = ( - obj_analysis.dc_parameter[0] - ) - json_data["analysis"]["dc"]["Increment Combo"] = ( - obj_analysis.dc_parameter[1] - ) - json_data["analysis"]["dc"]["Stop Combo"] = ( - obj_analysis.dc_parameter[2] - ) - json_data["analysis"]["dc"]["Source 2"] = str( - obj_analysis.dc_entry_var[4].text()) - json_data["analysis"]["dc"]["Start2"] = str( - obj_analysis.dc_entry_var[5].text()) - json_data["analysis"]["dc"]["Increment2"] = str( - obj_analysis.dc_entry_var[6].text()) - json_data["analysis"]["dc"]["Stop2"] = str( - obj_analysis.dc_entry_var[7].text()) - json_data["analysis"]["dc"]["Start Combo2"] = ( - obj_analysis.dc_parameter[3] - ) - json_data["analysis"]["dc"]["Increment Combo2"] = ( - obj_analysis.dc_parameter[4] - ) - json_data["analysis"]["dc"]["Stop Combo2"] = ( - obj_analysis.dc_parameter[5] - ) + ET.SubElement(attr_ac, "field1", name="Lin").text = "false" + ET.SubElement(attr_ac, "field2", name="Dec").text = "false" + ET.SubElement(attr_ac, "field3", name="Oct").text = "true" + + ET.SubElement( + attr_ac, "field4", name="Start Frequency" + ).text = str(obj_analysis.ac_entry_var[0].text()) + ET.SubElement( + attr_ac, "field5", name="Stop Frequency" + ).text = str(obj_analysis.ac_entry_var[1].text()) + ET.SubElement( + attr_ac, "field6", name="No. of points" + ).text = str(obj_analysis.ac_entry_var[2].text()) + ET.SubElement( + attr_ac, "field7", name="Start Fre Combo" + ).text = obj_analysis.ac_parameter[0] + ET.SubElement( + attr_ac, "field8", name="Stop Fre Combo" + ).text = obj_analysis.ac_parameter[1] + + attr_dc = ET.SubElement(attr_analysis, "dc") + + ET.SubElement( + attr_dc, "field1", name="Source 1" + ).text = str(obj_analysis.dc_entry_var[0].text()) + ET.SubElement( + attr_dc, "field2", name="Start" + ).text = str(obj_analysis.dc_entry_var[1].text()) + ET.SubElement( + attr_dc, "field3", name="Increment" + ).text = str(obj_analysis.dc_entry_var[2].text()) + ET.SubElement( + attr_dc, "field4", name="Stop" + ).text = str(obj_analysis.dc_entry_var[3].text()) + # print("OBJ_ANALYSIS.CHECK -----", self.obj_track.op_check[-1]) + ET.SubElement( + attr_dc, "field5", name="Operating Point" + ).text = str(self.obj_track.op_check[-1]) + ET.SubElement( + attr_dc, "field6", name="Start Combo" + ).text = obj_analysis.dc_parameter[0] + ET.SubElement( + attr_dc, "field7", name="Increment Combo" + ).text = obj_analysis.dc_parameter[1] + ET.SubElement( + attr_dc, "field8", name="Stop Combo" + ).text = obj_analysis.dc_parameter[2] + ET.SubElement( + attr_dc, "field9", name="Source 2" + ).text = str(obj_analysis.dc_entry_var[4].text()) + ET.SubElement( + attr_dc, "field10", name="Start" + ).text = str(obj_analysis.dc_entry_var[5].text()) + ET.SubElement( + attr_dc, "field11", name="Increment" + ).text = str(obj_analysis.dc_entry_var[6].text()) + ET.SubElement( + attr_dc, "field12", name="Stop" + ).text = str(obj_analysis.dc_entry_var[7].text()) + ET.SubElement( + attr_dc, "field13", name="Start Combo" + ).text = obj_analysis.dc_parameter[3] + ET.SubElement( + attr_dc, "field14", name="Increment Combo" + ).text = obj_analysis.dc_parameter[4] + ET.SubElement( + attr_dc, "field15", name="Stop Combo" + ).text = obj_analysis.dc_parameter[5] + + attr_tran = ET.SubElement(attr_analysis, "tran") + ET.SubElement( + attr_tran, "field1", name="Start Time" + ).text = str(obj_analysis.tran_entry_var[0].text()) + ET.SubElement( + attr_tran, "field2", name="Step Time" + ).text = str(obj_analysis.tran_entry_var[1].text()) + ET.SubElement( + attr_tran, "field3", name="Stop Time" + ).text = str(obj_analysis.tran_entry_var[2].text()) + ET.SubElement( + attr_tran, "field4", name="Start Combo" + ).text = obj_analysis.tran_parameter[0] + ET.SubElement( + attr_tran, "field5", name="Step Combo" + ).text = obj_analysis.tran_parameter[1] + ET.SubElement( + attr_tran, "field6", name="Stop Combo" + ).text = obj_analysis.tran_parameter[2] + # print("TRAN PARAMETER 2-----",obj_analysis.tran_parameter[2]) + + if check == 0: + attr_source = ET.SubElement(attr_parent, "source") + if check == 1: + for child in attr_parent: + if child.tag == "source": + attr_source = child - json_data["analysis"]["tran"] = {} - json_data["analysis"]["tran"]["Start Time"] = str( - obj_analysis.tran_entry_var[0].text()) - json_data["analysis"]["tran"]["Step Time"] = str( - obj_analysis.tran_entry_var[1].text()) - json_data["analysis"]["tran"]["Stop Time"] = str( - obj_analysis.tran_entry_var[2].text()) - json_data["analysis"]["tran"]["Start Combo"] = ( - obj_analysis.tran_parameter[0] - ) - json_data["analysis"]["tran"]["Step Combo"] = ( - obj_analysis.tran_parameter[1] - ) - json_data["analysis"]["tran"]["Stop Combo"] = ( - obj_analysis.tran_parameter[2] - ) - - # Writing source values - json_data["source"] = {} count = 1 + grand_child_count = 1 - for line in store_schematicInfo: - words = line.split(' ') + for i in store_schematicInfo: + tmp_check = 0 + words = i.split(' ') wordv = words[0] - - if wordv[0] == "v" or wordv[0] == "i": - json_data["source"][wordv] = {} - json_data["source"][wordv]["type"] = words[len(words) - 1] - json_data["source"][wordv]["values"] = [] - - if words[len(words) - 1] == "ac": - amp = {"Amplitude": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(amp) - - phase = {"Phase": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(phase) - - elif words[len(words) - 1] == "dc": - value = {"Value": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(value) - - elif words[len(words) - 1] == "sine": - offset = { - "Offset Value": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(offset) - - amp = {"Amplitude": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(amp) - - freq = {"Freuency": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(freq) - - delay = {"Delay Time": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(delay) - - damp = { - "Damping Factor": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(damp) - - elif words[len(words) - 1] == "pulse": - initial = { - "Initial Value": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(initial) - - pulse = { - "Pulse Value": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(pulse) - - delay = {"Delay Time": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(delay) - - rise = {"Rise Time": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(rise) - - fall = {"Fall Time": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(fall) - - width = { - "Pulse width": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(width) - - period = {"Period": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(period) - - elif words[len(words) - 1] == "pwl": - pwl = { - "Enter in pwl format": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(pwl) - - elif words[len(words) - 1] == "exp": - initial = { - "Initial Value": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(initial) - - pulsed = { - "Pulsed Value": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(pulsed) - - rise = { - "Rise Delay Time": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(rise) - - fall = {"Fall Time": str(obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(fall) - - fallConstant = { - "Fall Time Constant": str( - obj_source.entry_var[count].text())} - count += 1 - json_data["source"][wordv]["values"].append(fallConstant) - - else: - pass - - # Writing Model values - + for child in attr_source: + if child.tag == wordv and child.text == words[len(words) - 1]: + tmp_check = 1 + for grand_child in child: + grand_child.text = \ + str(obj_source.entry_var[grand_child_count].text()) + grand_child_count += 1 + grand_child_count += 1 + if tmp_check == 0: + words = i.split(' ') + wordv = words[0] + if wordv[0] == "v" or wordv[0] == "i": + attr_var = ET.SubElement( + attr_source, words[0], name="Source type" + ) + attr_var.text = words[len(words) - 1] + # ET.SubElement( + # attr_ac, "field1", name="Lin").text = "true" + if words[len(words) - 1] == "ac": + # attr_ac = ET.SubElement(attr_var, "ac") + ET.SubElement( + attr_var, "field1", name="Amplitude" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field2", name="Phase" + ).text = str(obj_source.entry_var[count].text()) + count += 2 + elif words[len(words) - 1] == "dc": + # attr_dc = ET.SubElement(attr_var, "dc") + ET.SubElement( + attr_var, "field1", name="Value" + ).text = str(obj_source.entry_var[count].text()) + count += 2 + elif words[len(words) - 1] == "sine": + # attr_sine = ET.SubElement(attr_var, "sine") + ET.SubElement( + attr_var, "field1", name="Offset Value" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field2", name="Amplitude" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field3", name="Frequency" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field4", name="Delay Time" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field5", name="Damping Factor" + ).text = str(obj_source.entry_var[count].text()) + count += 2 + elif words[len(words) - 1] == "pulse": + # attr_pulse=ET.SubElement(attr_var,"pulse") + ET.SubElement( + attr_var, "field1", name="Initial Value" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field2", name="Pulse Value" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field3", name="Delay Time" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field4", name="Rise Time" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field5", name="Fall Time" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field5", name="Pulse width" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field5", name="Period" + ).text = str(obj_source.entry_var[count].text()) + count += 2 + elif words[len(words) - 1] == "pwl": + # attr_pwl=ET.SubElement(attr_var,"pwl") + ET.SubElement( + attr_var, "field1", name="Enter in pwl format" + ).text = str(obj_source.entry_var[count].text()) + count += 2 + elif words[len(words) - 1] == "exp": + # attr_exp=ET.SubElement(attr_var,"exp") + ET.SubElement( + attr_var, "field1", name="Initial Value" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field2", name="Pulsed Value" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field3", name="Rise Delay Time" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field4", name="Rise Time Constant" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field5", name="Fall TIme" + ).text = str(obj_source.entry_var[count].text()) + count += 1 + ET.SubElement( + attr_var, "field6", name="Fall Time Constant" + ).text = str(obj_source.entry_var[count].text()) + count += 2 + + if check == 0: + attr_model = ET.SubElement(attr_parent, "model") + if check == 1: + for child in attr_parent: + if child.tag == "model": + attr_model = child i = 0 - json_data["model"] = {} + + # tmp_check is a variable to check for duplicates in the xml file + tmp_check = 0 + # tmp_i is the iterator in case duplicates are there; + # then in that case we need to replace only the child node and + # not create a new parent node for line in modelList: + tmp_check = 0 for rand_itr in obj_model.obj_trac.modelTrack: if rand_itr[2] == line[2] and rand_itr[3] == line[3]: start = rand_itr[7] end = rand_itr[8] - i = start - json_data["model"][line[3]] = {} - json_data["model"][line[3]]["type"] = line[2] - json_data["model"][line[3]]["values"] = [] - - for key, value in line[7].items(): - if( - hasattr(value, '__iter__') and - i <= end and not isinstance(value, str) - ): - for item in value: - fields = { - item: str( - obj_model.obj_trac.model_entry_var[i].text())} - json_data["model"][line[3]]["values"].append(fields) + i = start + for child in attr_model: + if child.text == line[2] and child.tag == line[3]: + for grand_child in child: + if i <= end: + grand_child.text = \ + str(obj_model.obj_trac.model_entry_var[i].text()) + i = i + 1 + tmp_check = 1 + + if tmp_check == 0: + attr_ui = ET.SubElement(attr_model, line[3], name="type") + attr_ui.text = line[2] + for key, value in line[7].items(): + if( + hasattr(value, '__iter__') and + i <= end and not isinstance(value, str) + ): + for item in value: + ET.SubElement( + attr_ui, "field" + str(i + 1), name=item + ).text = str( + obj_model.obj_trac.model_entry_var[i].text() + ) + i = i + 1 + + else: + ET.SubElement( + attr_ui, "field" + str(i + 1), name=value + ).text = str( + obj_model.obj_trac.model_entry_var[i].text() + ) i = i + 1 - else: - fields = { - value: str( - obj_model.obj_trac.model_entry_var[i].text())} - json_data["model"][line[3]]["values"].append(fields) - i = i + 1 - # Writing Device Model values - - json_data["deviceModel"] = {} + if check == 0: + attr_devicemodel = ET.SubElement(attr_parent, "devicemodel") + if check == 1: + for child in attr_parent: + if child.tag == "devicemodel": + del child[:] + attr_devicemodel = child for device in obj_devicemodel.devicemodel_dict_beg: - json_data["deviceModel"][device] = [] + attr_var = ET.SubElement(attr_devicemodel, device) it = obj_devicemodel.devicemodel_dict_beg[device] end = obj_devicemodel.devicemodel_dict_end[device] while it <= end: - json_data["deviceModel"][device].append( - str(obj_devicemodel.entry_var[it].text())) + ET.SubElement(attr_var, "field").text = \ + str(obj_devicemodel.entry_var[it].text()) it = it + 1 # Writing Subcircuit values + if check == 0: + attr_subcircuit = ET.SubElement(attr_parent, "subcircuit") + if check == 1: + for child in attr_parent: + if child.tag == "subcircuit": + del child[:] + attr_subcircuit = child - json_data["subcircuit"] = {} for subckt in obj_subcircuitTab.subcircuit_dict_beg: - json_data["subcircuit"][subckt] = [] + attr_var = ET.SubElement(attr_subcircuit, subckt) it = obj_subcircuitTab.subcircuit_dict_beg[subckt] end = obj_subcircuitTab.subcircuit_dict_end[subckt] while it <= end: - json_data["subcircuit"][subckt].append( - str(obj_subcircuitTab.entry_var[it].text())) + ET.SubElement(attr_var, "field").text = \ + str(obj_subcircuitTab.entry_var[it].text()) it = it + 1 - # json dumped and written to previous value file for the project - write_data = json.dumps(json_data) - fw.write(write_data) + # xml written to previous value file for the project + tree = ET.ElementTree(attr_parent) + tree.write(fw) # Create Convert object with the source details & the schematic details print("=============================================================") @@ -594,11 +661,11 @@ class MainWindow(QtGui.QWidget): print("=========================================================") self.createNetlistFile(store_schematicInfo, plotText) - self.msg = "The Kicad to Ngspice Conversion completed\ - successfully!" + self.msg = "The Kicad to Ngspice Conversion completed " + self.msg += "successfully!" QtGui.QMessageBox.information( - self, "Information", self.msg, QtGui.QMessageBox.Ok) - + self, "Information", self.msg, QtGui.QMessageBox.Ok + ) except Exception as e: print("Exception Message: ", e) print("There was error while converting kicad to ngspice") @@ -615,31 +682,26 @@ class MainWindow(QtGui.QWidget): """ - Creating .cir.out file - If analysis file present uses that and extract - - - Simulator - - - Initial - - - Analysis + - Simulator + - Initial + - Analysis - Finally add the following components to .cir.out file - - - SimulatorOption - - - InitialCondOption - - - Store_SchematicInfo - - - AnalysisOption + - SimulatorOption + - InitialCondOption + - Store_SchematicInfo + - AnalysisOption - In the end add control statements and allv, alli, end statements """ print("=============================================================") print("Creating Final netlist") - # print "INFOLINE",infoline - # print "OPTIONINFO",optionInfo - # print "Device MODEL LIST ",devicemodelList - # print "SUBCKT ",subcktList - # print "OUTPUTOPTION",outputOption - # print "KicadfIle",kicadFile + # To avoid writing optionInfo twice in final netlist store_optionInfo = list(optionInfo) # checking if analysis files is present (projpath, filename) = os.path.split(self.kicadFile) analysisFileLoc = os.path.join(projpath, "analysis") - # print "Analysis File Location",analysisFileLoc + if os.path.exists(analysisFileLoc): try: f = open(analysisFileLoc) @@ -653,7 +715,7 @@ class MainWindow(QtGui.QWidget): Please check it") sys.exit() else: - print("========================================================") + # print("========================================================") print(analysisFileLoc + " does not exist") sys.exit() @@ -664,10 +726,7 @@ class MainWindow(QtGui.QWidget): if len(eachline) > 1: if eachline[0] == '.': store_optionInfo.append(eachline) - else: - pass - # print "Option Info",optionInfo analysisOption = [] initialCondOption = [] simulatorOption = [] @@ -743,7 +802,7 @@ class MainWindow(QtGui.QWidget): except BaseException: print("Error in opening .cir.out file.") else: - print("=========================================================") + # print("=========================================================") print( self.projName + ".cir.out does not exist. Please create a spice netlist.") @@ -751,8 +810,8 @@ class MainWindow(QtGui.QWidget): # Read the data from file data = f.read() # Close the file - f.close() + newNetlist = [] netlist = iter(data.splitlines()) for eachline in netlist: @@ -803,5 +862,5 @@ class MainWindow(QtGui.QWidget): out.writelines('\n') out.writelines('.ends ' + self.projName) - print("=============================================================") + # print("=============================================================") print("The subcircuit has been written in " + self.projName + ".sub") diff --git a/src/kicadtoNgspice/Model.py b/src/kicadtoNgspice/Model.py index a182dd4e..a5757702 100644 --- a/src/kicadtoNgspice/Model.py +++ b/src/kicadtoNgspice/Model.py @@ -1,7 +1,6 @@ from PyQt4 import QtGui -import json from . import TrackWidget -# from xml.etree import ElementTree as ET +from xml.etree import ElementTree as ET import os @@ -19,18 +18,23 @@ class Model(QtGui.QWidget): kicadFile = clarg1 (projpath, filename) = os.path.split(kicadFile) project_name = os.path.basename(projpath) - + check = 1 try: f = open( os.path.join( projpath, project_name + - "_Previous_Values.json"), + "_Previous_Values.xml"), 'r') - data = f.read() - json_data = json.loads(data) + tree = ET.parse(f) + parent_root = tree.getroot() + for child in parent_root: + if child.tag == "model": + root = child + except BaseException: - print("Model Previous Values JSON is Empty") + check = 0 + print("Model Previous Values XML is Empty") # Creating track widget object self.obj_trac = TrackWidget.TrackWidget() @@ -59,8 +63,6 @@ class Model(QtGui.QWidget): # line[7] is parameter dictionary holding parameter tags. i = 0 for key, value in line[7].items(): - # print "Key : ",key - # print "Value : ",value # Check if value is iterable if not isinstance(value, str) and hasattr(value, '__iter__'): # For tag having vector value @@ -76,17 +78,11 @@ class Model(QtGui.QWidget): [self.nextcount], self.nextrow, 1) try: - for mod in json_data["model"]: - if json_data["model"][mod]["type"] ==\ - line[2] and mod == line[3]: - ( - self.obj_trac.model_entry_var - [self.nextcount].setText( - str(list( - json_data - ["model"][mod]["values"] - [i].values())[0])) - ) + for child in root: + if child.text == line[2] \ + and child.tag == line[3]: + self.obj_trac.model_entry_var + [self.nextcount].setText(child[i].text) i = i + 1 except BaseException: pass @@ -108,26 +104,18 @@ class Model(QtGui.QWidget): ) try: - for mod in json_data["model"]: - if json_data["model"][mod]["type"] ==\ - line[2] and mod == line[3]: - ( - self.obj_trac.model_entry_var - [self.nextcount].setText( - str(list(json_data - ["model"][mod]["values"] - [i].values())[0])) - ) + for child in root: + if child.text == line[2] and child.tag == line[3]: + self.obj_trac.model_entry_var[self.nextcount] \ + .setText(child[i].text) i = i + 1 except BaseException: pass - tag_dict[key] = self.nextcount self.nextcount = self.nextcount + 1 self.nextrow = self.nextrow + 1 self.end = self.nextcount - 1 - # print "End",self.end modelbox.setLayout(modelgrid) # CSS @@ -173,6 +161,4 @@ class Model(QtGui.QWidget): if check == 0: self.obj_trac.modelTrack.append(lst) - # print "The tag dictionary : ",tag_dict - self.show() diff --git a/src/kicadtoNgspice/Processing.py b/src/kicadtoNgspice/Processing.py index a0f2c79f..67ffd3f5 100644 --- a/src/kicadtoNgspice/Processing.py +++ b/src/kicadtoNgspice/Processing.py @@ -8,35 +8,33 @@ class PrcocessNetlist: - This class include all the function required for pre-proccessing of netlist before converting to Ngspice Netlist. """ - modelxmlDIR = '../modelParamXML' + modelxmlDIR = 'library/modelParamXML' def __init__(self): pass - """ - - Read the circuit file and return splitted lines - """ - def readNetlist(self, filename): + """ + - Read the circuit file and return splitted lines + """ f = open(filename) data = f.read() f.close() - print("=============================================================") - print("readNetList called, from Processing") - print("=============================================================") - print("NETLIST", data.splitlines()) - print("=============================================================") + # print("=============================================================") + # print("readNetList called, from Processing") + # print("=============================================================") + # print("NETLIST", data.splitlines()) + # print("=============================================================") return data.splitlines() - """ - - Read Parameter information and store it into dictionary - - kicadNetlis is the .cir file content - """ - - def readParamInfo(self, kicadNetlis): + def readParamInfo(self, kicadNetlist): + """ + - Read Parameter information and store it into dictionary + - kicadNetlist is the .cir file content + """ param = {} - print("=========================KICADNETLIST========================") - for eachline in kicadNetlis: + # print("=========================KICADNETLIST========================") + for eachline in kicadNetlist: print(eachline) eachline = eachline.strip() if len(eachline) > 1: @@ -46,21 +44,20 @@ class PrcocessNetlist: for i in range(1, len(words), 1): paramList = words[i].split('=') param[paramList[0]] = paramList[1] - print("=============================================================") - print("readParamInfo called, from Processing") - print("=============================================================") - print("PARAM", param) - print("=============================================================") + # print("=============================================================") + # print("readParamInfo called, from Processing") + # print("=============================================================") + # print("PARAM", param) + # print("=============================================================") return param - """ - - Preprocess netlist (replace parameters) - - Separate infoline (first line) from the rest of netlist - """ - - def preprocessNetlist(self, kicadNetlis, param): + def preprocessNetlist(self, kicadNetlist, param): + """ + - Preprocess netlist (replace parameters) + - Separate infoline (first line) from the rest of netlist + """ netlist = [] - for eachline in kicadNetlis: + for eachline in kicadNetlist: # Remove leading and trailing blanks spaces from line eachline = eachline.strip() # Remove special character $ @@ -89,12 +86,12 @@ class PrcocessNetlist: # Copy information line infoline = netlist[0] netlist.remove(netlist[0]) - print("=============================================================") + """print("=============================================================") print("preprocessNetList called, from Processing") print("=============================================================") print("NETLIST", netlist) print("INFOLINE", infoline) - print("=============================================================") + print("===========================================================")""" return netlist, infoline def separateNetlistInfo(self, netlist): @@ -114,26 +111,25 @@ class PrcocessNetlist: optionInfo.append(eachline) else: schematicInfo.append(eachline) - print("=============================================================") + """print("=============================================================") print("separateNetlistInfo called, from Processing") print("=============================================================") print("OPTIONINFO", optionInfo) print("SCHEMATICINFO", schematicInfo) - print("=============================================================") + print("===========================================================")""" return optionInfo, schematicInfo - """ - - Insert Special source parameter - - As per the parameters passed create source list, start with v or i - - Then check for type whether ac, dc, sine, etc... - - Handle starting with h and f as well - """ - def insertSpecialSourceParam(self, schematicInfo, sourcelist): + """ + - Insert Special source parameter + - As per the parameters passed create source list, start with v or i + - Then check for type whether ac, dc, sine, etc... + - Handle starting with h and f as well + """ schematicInfo1 = [] - print("=============================================================") - print("Reading schematic info for source details") - print("=============================================================") + # print("=============================================================") + # print("Reading schematic info for source details") + # print("=============================================================") for compline in schematicInfo: words = compline.split() compName = words[0] @@ -217,14 +213,14 @@ class PrcocessNetlist: words[5]) schematicInfo = schematicInfo + schematicInfo1 - print("Source List : ", sourcelist) - # print schematicInfo - print("=============================================================") + # print("Source List : ", sourcelist) + + """print("=============================================================") print("insertSpecialSourceParam called, from Processing") print("=============================================================") print("SCHEMATICINFO", schematicInfo) print("SOURCELIST", sourcelist) - print("=============================================================") + print("===========================================================")""" return schematicInfo, sourcelist def convertICintoBasicBlocks( @@ -239,8 +235,8 @@ class PrcocessNetlist: - - Plot text - Parsing info is provided below """ - print("=============================================================") - print("Reading Schematic info for Model") + # print("=============================================================") + # print("Reading Schematic info for Model") # Insert details of Ngspice model unknownModelList = [] multipleModelList = [] @@ -293,8 +289,8 @@ class PrcocessNetlist: unknownModelList.append(compType) elif count == 1: try: - print("==========================================\ - ===========================") + # print("==========================================\ + # ===========================") print( "Start Parsing Previous Values XML\ for ngspice model :", modelPath) @@ -355,9 +351,9 @@ class PrcocessNetlist: modelLine += compName else: - print("=====================================\ - ================================") - print("Split Details :", splitDetail) + # print("=====================================\ + # ================================") + # print("Split Details :", splitDetail) modelLine = "a" + str(k) + " " vectorDetail = splitDetail.split(':') # print "Vector Details",vectorDetail @@ -507,7 +503,7 @@ class PrcocessNetlist: else: schematicInfo.insert(index, "* " + compline) - print("=====================================================") + # print("=====================================================") print( "UnknownModelList Used in the Schematic", unknownModelList) @@ -516,7 +512,7 @@ class PrcocessNetlist: "Multiple Model XML file with same name ", multipleModelList) print("=====================================================") - print("Model List Details : ", modelList) + # print("Model List Details : ", modelList) print("=============================================================") print("convertICIntoBasicBlocks called, from Processing") print("=============================================================") diff --git a/src/kicadtoNgspice/Source.py b/src/kicadtoNgspice/Source.py index 26555197..e42899e3 100644 --- a/src/kicadtoNgspice/Source.py +++ b/src/kicadtoNgspice/Source.py @@ -1,8 +1,7 @@ import os from PyQt4 import QtGui from . import TrackWidget -# from xml.etree import ElementTree as ET -import json +from xml.etree import ElementTree as ET class Source(QtGui.QWidget): @@ -13,7 +12,7 @@ class Source(QtGui.QWidget): def __init__(self, sourcelist, sourcelisttrack, clarg1): QtGui.QWidget.__init__(self) self.obj_track = TrackWidget.TrackWidget() - # Variable + # Variables self.count = 1 self.clarg1 = clarg1 self.start = 0 @@ -45,10 +44,10 @@ class Source(QtGui.QWidget): - Each line in sourcelist corresponds to a source - According to the source type modify the source and add it to the tab """ - print("============================================================") + """print("============================================================") print("SOURCE LIST TRACK", sourcelisttrack) print("SOURCE LIST", sourcelist) - print("============================================================") + print("===========================================================")""" kicadFile = self.clarg1 (projpath, filename) = os.path.split(kicadFile) project_name = os.path.basename(projpath) @@ -58,23 +57,24 @@ class Source(QtGui.QWidget): os.path.join( projpath, project_name + - "_Previous_Values.json"), + "_Previous_Values.xml"), 'r') - data = f.read() - json_data = json.loads(data) - + tree = ET.parse(f) + parent_root = tree.getroot() + for child in parent_root: + if child.tag == "source": + root = child except BaseException: - print("Source Previous Values JSON is Empty") + print("Source Previous Values XML is Empty") self.grid = QtGui.QGridLayout() self.setLayout(self.grid) + xml_num = 0 if sourcelist: for line in sourcelist: - # print "Voltage source line index: ",line[0] print("SourceList line: ", line) track_id = line[0] - # print "track_id is ",track_id if line[2] == 'ac': acbox = QtGui.QGroupBox() acbox.setTitle(line[3]) @@ -88,34 +88,23 @@ class Source(QtGui.QWidget): self.entry_var[self.count] = QtGui.QLineEdit() self.entry_var[self.count].setMaximumWidth(150) acgrid.addWidget(self.entry_var[self.count], self.row, 1) - self.entry_var[self.count].setText("") - self.count += 1 - - self.entry_var[self.count] = QtGui.QLineEdit() - self.entry_var[self.count].setMaximumWidth(150) + self.entry_var[self.count + 1] = QtGui.QLineEdit() + self.entry_var[self.count + 1].setMaximumWidth(150) acgrid.addWidget( - self.entry_var[self.count], self.row + 1, 1) + self.entry_var[self.count+1], self.row + 1, 1) self.entry_var[self.count].setText("") - self.count += 1 - + self.entry_var[self.count+1].setText("") try: - for key in json_data["source"]: + for child in root: templist1 = line[1] templist2 = templist1.split(' ') - if key == templist2[0] and \ - json_data["source"][key]["type"]\ - == line[2]: - self.entry_var[self.count - 2].setText( - str( - json_data - ["source"][key]["values"][0] - ["Amplitude"])) - self.entry_var[self.count - 1].setText( - str( - json_data["source"][key] - ["values"][1]["Phase"])) - + if child.tag == templist2[0] and \ + child.text == line[2]: + self.entry_var[self.count] \ + .setText(child[0].text) + self.entry_var[self.count + 1] \ + .setText(child[1].text) except BaseException: pass # Value Need to check previuouse value @@ -141,6 +130,7 @@ class Source(QtGui.QWidget): dcbox = QtGui.QGroupBox() dcbox.setTitle(line[3]) dcgrid = QtGui.QGridLayout() + self.row = self.row + 1 self.start = self.count label = QtGui.QLabel(line[4]) dcgrid.addWidget(label, self.row, 0) @@ -151,18 +141,14 @@ class Source(QtGui.QWidget): self.entry_var[self.count].setText("") try: - for key in json_data["source"]: + for child in root: templist1 = line[1] templist2 = templist1.split(' ') - if key == templist2[0] and \ - json_data["source"][key]["type"]\ - == line[2]: - self.entry_var[self.count].setText( - str( - json_data["source"][key] - ["values"][0]["Value"])) - + if child.tag == templist2[0] \ + and child.text == line[2]: + self.entry_var[self.count] \ + .setText(child[0].text) except BaseException: pass @@ -200,17 +186,13 @@ class Source(QtGui.QWidget): self.entry_var[self.count].setText("") try: - for key in json_data["source"]: + for child in root: templist1 = line[1] templist2 = templist1.split(' ') - if key == templist2[0] and \ - json_data["source"][key]["type"]\ - == line[2]: - self.entry_var[self.count].setText( - str( - list(json_data["source"] - [key]["values"] - [it - 4].values())[0])) + if child.tag == templist2[0] \ + and child.text == line[2]: + self.entry_var[self.count] \ + .setText(child[it-4].text) except BaseException: pass @@ -247,17 +229,13 @@ class Source(QtGui.QWidget): self.entry_var[self.count].setText("") try: - for key in json_data["source"]: + for child in root: templist1 = line[1] templist2 = templist1.split(' ') - - if key == templist2[0] and \ - json_data["source"][key]["type"]\ - == line[2]: - self.entry_var[self.count].setText( - str(list( - json_data["source"][key] - ["values"][it - 4].values())[0])) + if child.tag == templist2[0] \ + and child.text == line[2]: + self.entry_var[self.count] \ + .setText(child[it-4].text) except BaseException: pass @@ -291,15 +269,13 @@ class Source(QtGui.QWidget): self.entry_var[self.count].setText("") try: - for key in json_data["source"]: + for child in root: templist1 = line[1] templist2 = templist1.split(' ') - if key == templist2[0] and \ - json_data["source"][key]["type"] \ - == line[2]: - self.entry_var[self.count].setText( - str(json_data["source"][key] - ["values"][0]["Enter in pwl format"])) + if child.tag == templist2[0] \ + and child.text == line[2]: + self.entry_var[self.count] \ + .setText(child[0].text) except BaseException: pass @@ -336,19 +312,13 @@ class Source(QtGui.QWidget): self.entry_var[self.count].setText("") try: - for key in json_data["source"]: + for child in root: templist1 = line[1] templist2 = templist1.split(' ') - if key == templist2[0] and \ - json_data["source"][key]["type"]\ - == line[2]: - self.entry_var[self.count].setText( - str( - list( - json_data["source"][key] - ["values"][it - 4].values())[0] - ) - ) + if child.tag == templist2[0] \ + and child.text == line[2]: + self.entry_var[self.count] \ + .setText(child[it-4].text) except BaseException: pass @@ -369,10 +339,13 @@ class Source(QtGui.QWidget): sourcelisttrack.append( [track_id, 'exp', self.start, self.end]) + self.count = self.count + 1 + xml_num = xml_num + 1 + else: print("No source is present in your circuit") - print("============================================================") + # print("============================================================") # This is used to keep the track of dynamically created widget self.obj_track.sourcelisttrack["ITEMS"] = sourcelisttrack self.obj_track.source_entry_var["ITEMS"] = self.entry_var diff --git a/src/kicadtoNgspice/SubcircuitTab.py b/src/kicadtoNgspice/SubcircuitTab.py index d15407f7..a191c639 100644 --- a/src/kicadtoNgspice/SubcircuitTab.py +++ b/src/kicadtoNgspice/SubcircuitTab.py @@ -1,9 +1,8 @@ from PyQt4 import QtGui -import json from . import TrackWidget from projManagement import Validation import os -# from xml.etree import ElementTree as ET +from xml.etree import ElementTree as ET class SubcircuitTab(QtGui.QWidget): @@ -12,7 +11,7 @@ class SubcircuitTab(QtGui.QWidget): - It dynamically creates the widget for subcircuits, according to the .cir file - Creates `lineEdit` and `Add` button, which triggers `fileSelector` - - Also, checks `Previous_value.json` for previous subcircuit value + - Also, checks `Previous_value.xml` for previous subcircuit value to autofill, the `lineEdit` - Add button is bind to `trackSubcircuit` - Also `trackSubcircuit` without button is triggered if `lineEdit` filled @@ -28,12 +27,15 @@ class SubcircuitTab(QtGui.QWidget): os.path.join( projpath, project_name + - "_Previous_Values.json"), + "_Previous_Values.xml"), 'r') - data = f.read() - json_data = json.loads(data) + tree = ET.parse(f) + parent_root = tree.getroot() + for child in parent_root: + if child.tag == "subcircuit": + root = child except BaseException: - print("Subcircuit Previous values JSON is Empty") + print("Subcircuit Previous values XML is Empty") QtGui.QWidget.__init__(self) @@ -61,7 +63,7 @@ class SubcircuitTab(QtGui.QWidget): for eachline in schematicInfo: words = eachline.split() if eachline[0] == 'x': - print("Subcircuit : Words", words[0]) + # print("Subcircuit : Words", words[0]) self.obj_trac.subcircuitList[project_name + words[0]] = words self.subcircuit_dict_beg[words[0]] = self.count subbox = QtGui.QGroupBox() @@ -72,16 +74,16 @@ class SubcircuitTab(QtGui.QWidget): global path_name try: - for key in json_data["subcircuit"]: - if key == words[0]: - # print "Subcircuit MATCHING---",child.tag[0], \ - # child.tag[1], eachline[0], eachline[1] + for child in root: + if child.tag[0] == eachline[0] \ + and child.tag[1] == eachline[1]: + # print("Subcircuit MATCHING---", child.tag[0], \ + # child.tag[1], eachline[0],eachline[1]) try: - if os.path.exists( - json_data["subcircuit"][key][0]): - self.entry_var[self.count].setText( - json_data["subcircuit"][key][0]) - path_name = json_data["subcircuit"][key][0] + if os.path.exists(child[0].text): + self.entry_var[self.count] \ + .setText(child[0].text) + path_name = child[0].text else: self.entry_var[self.count].setText("") except BaseException: @@ -97,7 +99,7 @@ class SubcircuitTab(QtGui.QWidget): # eg. If the line is 'x1 4 0 3 ua741', there are 3 ports(4, 0 # and 3). self.numPorts.append(len(words) - 2) - print("Number of ports of sub circuit : ", self.numPorts) + # print("Number of ports of sub circuit : ", self.numPorts) self.addbtn.clicked.connect(self.trackSubcircuit) subgrid.addWidget(self.addbtn, self.row, 2) subbox.setLayout(subgrid) @@ -144,9 +146,9 @@ class SubcircuitTab(QtGui.QWidget): self.subfile = str( QtGui.QFileDialog.getExistingDirectory( - self, - "Open Subcircuit", - "../SubcircuitLibrary")) + self, "Open Subcircuit", + "library/SubcircuitLibrary") + ) self.reply = self.obj_validation.validateSub( self.subfile, self.numPorts[self.widgetObjCount - 1]) if self.reply == "True": @@ -159,17 +161,19 @@ class SubcircuitTab(QtGui.QWidget): self.obj_trac.subcircuitTrack[self.subName] = self.subfile elif self.reply == "PORT": self.msg = QtGui.QErrorMessage(self) + self.msg.setModal(True) + self.msg.setWindowTitle("Error Message") self.msg.showMessage( "Please select a Subcircuit with correct number of ports.") - self.msg.setWindowTitle("Error Message") - self.msg.show() + self.msg.exec_() elif self.reply == "DIREC": self.msg = QtGui.QErrorMessage(self) - self.msg.showMessage( - "Please select a valid Subcircuit directory \ - (Containing '.sub' file).") + self.msg.setModal(True) self.msg.setWindowTitle("Error Message") - self.msg.show() + self.msg.showMessage( + "Please select a valid Subcircuit directory " + "(Containing '.sub' file).") + self.msg.exec_() def trackSubcircuitWithoutButton(self, iter_value, path_value): """ @@ -189,18 +193,19 @@ class SubcircuitTab(QtGui.QWidget): self.subName = self.subDetail[self.widgetObjCount] # Storing to track it during conversion - self.obj_trac.subcircuitTrack[self.subName] = self.subfile elif self.reply == "PORT": self.msg = QtGui.QErrorMessage(self) + self.msg.setModal(True) + self.msg.setWindowTitle("Error Message") self.msg.showMessage( "Please select a Subcircuit with correct number of ports.") - self.msg.setWindowTitle("Error Message") - self.msg.show() + self.msg.exec_() elif self.reply == "DIREC": self.msg = QtGui.QErrorMessage(self) - self.msg.showMessage( - "Please select a valid Subcircuit directory \ - (Containing '.sub' file).") + self.msg.setModal(True) self.msg.setWindowTitle("Error Message") - self.msg.show() + self.msg.showMessage( + "Please select a valid Subcircuit directory " + "(Containing '.sub' file).") + self.msg.exec_() diff --git a/src/kicadtoNgspice/TrackWidget.py b/src/kicadtoNgspice/TrackWidget.py index ec5c2c81..3a8b0dac 100644 --- a/src/kicadtoNgspice/TrackWidget.py +++ b/src/kicadtoNgspice/TrackWidget.py @@ -2,11 +2,11 @@ class TrackWidget: """ - This Class track the dynamically created widget of KicadtoNgSpice Window. - Tracks using dictionary and lists ==> - - - Sources - - - Parameters - - - References - - - Model Details - - - ... etc + - Sources + - Parameters + - References + - Model Details + - ... etc """ # Track widget list for Source details sourcelisttrack = {"ITEMS": "None"} |