summaryrefslogtreecommitdiff
path: root/src/ngspiceSimulation/NgspiceWidget.py
blob: d6f7585317d9a8d4f45cce153cabcd58f8dda3ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from PyQt5 import QtWidgets, QtCore
from configuration.Appconfig import Appconfig
from frontEnd import TerminalUi


# This Class creates NgSpice Window
class NgspiceWidget(QtWidgets.QWidget):

    def __init__(self, command, simulationEssentials):
        """
        - Creates constructor for NgspiceWidget class.
        - Checks whether OS is Linux or Windows and
          creates Ngspice window accordingly.
        """
        QtWidgets.QWidget.__init__(self)
        self.obj_appconfig = Appconfig()
        self.process = QtCore.QProcess(self)
        self.projDir = self.obj_appconfig.current_project["ProjectName"]
        self.args = ['-b', '-r', command.replace(".cir.out", ".raw"), command]
        self.terminalUi = TerminalUi.TerminalUi(self.process, self.args)
        self.layout = QtWidgets.QVBoxLayout(self)
        self.layout.addWidget(self.terminalUi)
        self.checkChangeInPlotData = \
            simulationEssentials['checkChangeInPlotData']
        toggleToolbarButtons = simulationEssentials['toggleToolbarButtons']

        print("Argument to ngspice command : ", command)

        self.process.started.connect(lambda: toggleToolbarButtons(state=False))
        self.process.setWorkingDirectory(self.projDir)
        self.process.start('ngspice', self.args)
        self.process.readyReadStandardOutput.connect(
            lambda: self.readyReadAll())
        self.process.finished.connect(self.finishSimulation)
        self.obj_appconfig.process_obj.append(self.process)
        print(self.obj_appconfig.proc_dict)
        (
            self.obj_appconfig.proc_dict
            [self.obj_appconfig.current_project['ProjectName']].append(
                self.process.pid())
        )
        self.gawProcess = QtCore.QProcess(self)
        self.gawCommand = "gaw " + command.replace(".cir.out", ".raw")
        self.gawProcess.start('sh', ['-c', self.gawCommand])
        print(self.gawCommand)

    def finishSimulation(self, exitCode, exitStatus):
        """This function is intended to run when the ngspice
        simulation finishes. It singals to the function that generates
        the plots and also writes in the appropriate status of the
        simulation (Whether it was a success or not).

        :param exitCode: The exit code signal of the qprocess
            that runs ngspice
        :type exitCode: int
        :param exitStatus: The exit status signal of the
            qprocess that runs ngspice
        :type exitStatus: class:`QtCore.QProcess.ExitStatus`
        """

#       To stop progressbar from running after simulation is completed
        self.terminalUi.progressBar.setMaximum(100)
        self.terminalUi.progressBar.setProperty("value", 100)

        # st = os.stat(os.path.join(self.projDir, "plot_data_i.txt"))
        # if st.st_mtime >= self.currTime:
        if exitStatus == QtCore.QProcess.NormalExit:
            self.checkChangeInPlotData(exitCode)
#            self.terminalUi.writeSimulationStatusToConsole()

            failedFormat = '<span style="color:#ff3333; font-size:26px;"> \
                            {} \
                            </span>'
            successFormat = '<span style="color:#00ff00; font-size:26px;"> \
                            {} \
                            </span>'
            if exitCode == 0:
                self.terminalUi.simulationConsole.append(
                    successFormat.format("Simulation Completed Successfully!"))
            else:
                self.terminalUi.simulationConsole.append(
                    failedFormat.format("Simulation Failed!"))

            self.terminalUi.simulationConsole.verticalScrollBar().setValue(
                self.terminalUi.simulationConsole.verticalScrollBar().maximum()
            )
        else:
            self.msg = QtWidgets.QErrorMessage()
            self.msg.setModal(True)
            self.msg.setWindowTitle("Error Message")
            self.msg.showMessage(
                'Ngspice simulation did not complete successfully.'
            )
            self.msg.exec_()

    @QtCore.pyqtSlot()
    def readyReadAll(self):
        """Outputs the ngspice process standard output and standard error
        to :class:`TerminalUi.TerminalUi` console
        """
        self.terminalUi.simulationConsole.insertPlainText(
            str(self.process.readAllStandardOutput().data(), encoding='utf-8')
        )

        stderror = str(self.process.readAllStandardError().data(),
                       encoding='utf-8')
#       For suppressing the PrinterOnly error that batch mode throws
        stderror = '\n'.join([line for line in stderror.split('\n')
                              if ('PrinterOnly' not in line and
                              'viewport for graphics' not in line)])
        self.terminalUi.simulationConsole.insertPlainText(
            stderror
        )