Example #1
0
    def onReadSParametersFromFile(self):
        import SignalIntegrity.Lib as si
        filename=AskOpenFileName(filetypes=[('s-parameter files', ('*.s*p'))],
                                 initialdir=self.fileparts.AbsoluteFilePath(),
                                 parent=self)
        if filename is None:
            return
        self.fileparts=FileParts(filename)
        if self.fileparts.fileext=='':
            return

        self.title('S-parameters: '+self.fileparts.FileNameTitle())

        self.sp=si.sp.SParameterFile(filename)
        self.referenceImpedance.SetValueFromString(str(self.sp.m_Z0))
        self.referenceImpedanceProperty.propertyString.set(self.referenceImpedance.PropertyString(stype='entry'))
        for widget in self.sButtonsFrame.winfo_children():
            widget.destroy()
        numPorts=self.sp.m_P
        self.buttonLabels=[['s'+str(toP+1)+str(fromP+1) for fromP in range(numPorts)] for toP in range(numPorts)]
        self.buttons=[]
        for toP in range(numPorts):
            buttonrow=[]
            rowFrame=tk.Frame(self.sButtonsFrame)
            rowFrame.pack(side=tk.TOP,expand=tk.NO,fill=tk.NONE)
            for fromP in range(numPorts):
                thisButton=tk.Button(rowFrame,text=self.buttonLabels[toP][fromP],command=lambda x=toP+1,y=fromP+1: self.onSelectSParameter(x,y))
                thisButton.pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
                buttonrow.append(thisButton)
            self.buttons.append(buttonrow)
        self.fromPort = 1
        self.toPort = 1
        self.buttons[self.toPort-1][self.fromPort-1].config(relief=tk.SUNKEN)
        self.PlotSParameter()
 def OpenProjectFile(self, filename):
     if filename is None:
         filename = ''
     if isinstance(filename, tuple):
         filename = ''
     filename = str(filename)
     if filename == '':
         return False
     try:
         self.fileparts = FileParts(filename)
         os.chdir(self.fileparts.AbsoluteFilePath())
         self.fileparts = FileParts(filename)
         SignalIntegrity.App.Project = ProjectFile().Read(
             self.fileparts.FullFilePathExtension('.si'))
         self.Drawing.InitFromProject()
     except:
         return False
     self.Drawing.schematic.Consolidate()
     for device in self.Drawing.schematic.deviceList:
         device.selected = False
     for wireProject in SignalIntegrity.App.Project[
             'Drawing.Schematic.Wires']:
         for vertexProject in wireProject['Vertices']:
             vertexProject['Selected'] = False
     return True
Example #3
0
 def onTouched(self,event):
     fp=FileParts(self.fileparts.AbsoluteFilePath()+'/'+self.project[self.projectPath])
     filename=AskOpenFileName(filetypes=[('txt', '.txt')],
                             initialdir=fp.AbsoluteFilePath(),
                             initialfile=fp.FileNameWithExtension('txt'))
     if filename is None:
         return
     filename=ConvertFileNameToRelativePath(filename)
     self.project[self.projectPath]=filename
     self.UpdateStrings()
Example #4
0
    def onMatplotlib2TikZ(self):
        filename=AskSaveAsFilename(parent=self,filetypes=[('tex', '.tex')],
                                   defaultextension='.tex',
                                   initialdir=self.fileparts.AbsoluteFilePath(),
                                   initialfile=self.fileparts.filename+'Magnitude.tex')
        if filename is None:
            return

        try:
            PlotTikZ(filename,self.topLeftFigure)
        except:
            messagebox.showerror('Export LaTeX','LaTeX could not be generated or written ')                
        fp=FileParts(filename.replace('Magnitude.tex', ''))
        filename=fp.filename

        filename=AskSaveAsFilename(parent=self,filetypes=[('tex', '.tex')],
                                   defaultextension='.tex',
                                   initialdir=self.fileparts.AbsoluteFilePath(),
                                   initialfile=filename+'Phase.tex')
        if filename is None:
            return

        try:
            PlotTikZ(filename,self.topRightFigure)
        except:
            messagebox.showerror('Export LaTeX','LaTeX could not be generated or written ')                
        fp=FileParts(filename.replace('Phase.tex', ''))
        filename=fp.filename

        filename=AskSaveAsFilename(parent=self,filetypes=[('tex', '.tex')],
                                   defaultextension='.tex',
                                   initialdir=self.fileparts.AbsoluteFilePath(),
                                   initialfile=filename+'ImpulseResponse.tex')
        if filename is None:
            return

        try:
            PlotTikZ(filename,self.bottomLeftFigure)
        except:
            messagebox.showerror('Export LaTeX','LaTeX could not be generated or written ')                
        fp=FileParts(filename.replace('ImpulseResponse.tex', ''))
        filename=fp.filename

        filename=AskSaveAsFilename(parent=self,filetypes=[('tex', '.tex')],
                                   defaultextension='.tex',
                                   initialdir=self.fileparts.AbsoluteFilePath(),
                                   initialfile=filename+'StepResponse.tex')
        if filename is None:
            return

        try:
            PlotTikZ(filename,self.bottomRightFigure)
        except:
            messagebox.showerror('Export LaTeX','LaTeX could not be generated or written ')
Example #5
0
 def onWriteSParametersToFile(self):
     ports=self.sp.m_P
     extension='.s'+str(ports)+'p'
     filename=AskSaveAsFilename(filetypes=[('s-parameters', extension)],
                 defaultextension=extension,
                 initialdir=self.fileparts.AbsoluteFilePath(),
                 initialfile=self.fileparts.FileNameWithExtension(extension),
                 parent=self)
     if filename is None:
         return
     self.fileparts=FileParts(filename)
     self.sp.WriteToFile(filename,'R '+str(self.sp.m_Z0))
Example #6
0
 def onFileView(self):
     self.parentFrame.focus()
     filename = self.partProperty.GetValue()
     if filename != '':
         import SignalIntegrity.Lib as si
         if self.partProperty['PropertyName'] == 'filename':
             fp = FileParts(filename)
             if fp.fileext == '.si':
                 result = os.system('SignalIntegrity ' +
                                    os.path.abspath(filename) +
                                    ' --external')
                 if result != 0:
                     messagebox.showerror('ProjectFile',
                                          'could not be opened')
                     return
             else:
                 try:
                     sp = si.sp.SParameterFile(filename)
                 except si.SignalIntegrityException as e:
                     messagebox.showerror('S-parameter Viewer',
                                          e.parameter + ': ' + e.message)
                     return
                 spd = SParametersDialog(self.parent.parent.parent, sp,
                                         filename)
                 spd.grab_set()
         elif self.partProperty['PropertyName'] == 'waveformfilename':
             if FileParts(filename).fileext == '.si':
                 result = os.system('SignalIntegrity ' +
                                    os.path.abspath(filename) +
                                    ' --external')
                 if result != 0:
                     messagebox.showerror('ProjectFile',
                                          'could not be opened')
                     return
             else:
                 filenametoshow = ('/'.join(
                     filename.split('\\'))).split('/')[-1]
                 if filenametoshow is None:
                     filenametoshow = ''
                 try:
                     wf = self.parent.device.Waveform()
                 except si.SignalIntegrityException as e:
                     messagebox.showerror('Waveform Viewer',
                                          e.parameter + ': ' + e.message)
                     return
                 sd = SimulatorDialog(self.parent.parent)
                 sd.title(filenametoshow)
                 sd.UpdateWaveforms([wf], [filenametoshow])
                 sd.state('normal')
                 sd.grab_set()
Example #7
0
 def onEntered(self, event):
     self.partProperty.SetValueFromString(self.propertyString.get())
     if self.partProperty['PropertyName'] == 'waveformfilename':
         filename = self.partProperty.GetValue()
         isProject = FileParts(filename).fileext == '.si'
         for propertyFrame in self.parent.propertyFrameList:
             if propertyFrame.partProperty['PropertyName'] == 'wfprojname':
                 propertyFrame.partProperty['Hidden'] = not isProject
     self.callBack()
     self.onUntouchedLoseFocus(event)
Example #8
0
 def onFileBrowse(self):
     # this is a seemingly ugly workaround
     # I do this because when you change the number of ports and then touch the file
     # browse button, the ports are updated after this call based on the button press.
     # without this ugly thing, the file extension reflects the wrong number of ports
     # until the next time you press the button, when it is right.
     # This workaround forces the ports to be updated now.
     for pp in range(len(self.parent.device.propertiesList)):
         if self.parent.device.propertiesList[pp][
                 'PropertyName'] == 'ports':
             self.parent.propertyFrameList[pp].onUntouched(None)
     # end of ugly workaround
     self.callBack()
     if self.partProperty['PropertyName'] in ['filename', 'std']:
         extension = '.s' + self.device['ports'].PropertyString(
             stype='raw') + 'p'
         filetypename = 's-parameters'
     elif self.partProperty['PropertyName'] == 'waveformfilename':
         extension = '.txt'
         filetypename = 'waveforms'
     elif self.partProperty['PropertyName'] == 'errorterms':
         extension = '.cal'
         filetypename = 'calibration file'
     else:
         extension = ''
         filetypename = 'all'
     currentFileParts = FileParts(
         self.partProperty.PropertyString(stype='raw'))
     if currentFileParts.filename == '':
         initialDirectory = self.parent.parent.parent.fileparts.AbsoluteFilePath(
         )
         initialFile = ''
     else:
         initialDirectory = currentFileParts.AbsoluteFilePath()
         if currentFileParts.fileext in ['.si', extension]:
             initialFile = currentFileParts.FileNameWithExtension()
         else:
             initialFile = currentFileParts.filename + extension
     filename = AskOpenFileName(parent=self,
                                filetypes=[(filetypename, extension),
                                           ('project', '.si')],
                                initialdir=initialDirectory,
                                initialfile=initialFile)
     if filename is None:
         filename = ''
     if isinstance(filename, tuple):
         filename = ''
     filename = str(filename)
     if filename != '':
         filename = FileParts(filename).FullFilePathExtension()
         self.propertyString.set(filename)
         self.partProperty.SetValueFromString(self.propertyString.get())
         self.callBack()
     if self.partProperty['PropertyName'] == 'waveformfilename':
         filename = self.partProperty.GetValue()
         isProject = FileParts(filename).fileext == '.si'
         for propertyFrame in self.parent.propertyFrameList:
             if propertyFrame.partProperty['PropertyName'] == 'wfprojname':
                 propertyFrame.partProperty['Hidden'] = not isProject
     self.callBack()
Example #9
0
def AskOpenFileName(**kw):
    if 'filetypes' in kw:
        if 'initialfile' in kw:
            ext = FileParts(kw['initialfile']).fileext
            filetypes = kw['filetypes']
            filetypeext = [lext for (filetype, lext) in filetypes]
            if ext in filetypeext:
                extindex = filetypeext.index(ext)
                if extindex != 0:
                    kw['filetypes'] = [
                        filetypes[extindex]
                    ] + filetypes[0:extindex] + filetypes[extindex + 1:]
    filename = filedialog.askopenfilename(**kw)
    return _FileNameChecker(filename)
class SignalIntegrityAppHeadless(object):
    def __init__(self):
        # make absolutely sure the directory of this file is the first in the
        # python path
        thisFileDir = os.path.dirname(os.path.realpath(__file__))
        sys.path = [thisFileDir] + sys.path
        SignalIntegrity.App.Preferences = Preferences()
        SignalIntegrity.App.InstallDir = os.path.dirname(
            os.path.abspath(__file__))
        self.Drawing = DrawingHeadless(self)

    def NullCommand(self):
        pass

    def OpenProjectFile(self, filename):
        if filename is None:
            filename = ''
        if isinstance(filename, tuple):
            filename = ''
        filename = str(filename)
        if filename == '':
            return False
        try:
            self.fileparts = FileParts(filename)
            os.chdir(self.fileparts.AbsoluteFilePath())
            self.fileparts = FileParts(filename)
            SignalIntegrity.App.Project = ProjectFile().Read(
                self.fileparts.FullFilePathExtension('.si'))
            self.Drawing.InitFromProject()
        except:
            return False
        self.Drawing.schematic.Consolidate()
        for device in self.Drawing.schematic.deviceList:
            device.selected = False
        for wireProject in SignalIntegrity.App.Project[
                'Drawing.Schematic.Wires']:
            for vertexProject in wireProject['Vertices']:
                vertexProject['Selected'] = False
        return True

    def SaveProjectToFile(self, filename):
        self.fileparts = FileParts(filename)
        os.chdir(self.fileparts.AbsoluteFilePath())
        self.fileparts = FileParts(filename)
        SignalIntegrity.App.Project.Write(self, filename)

    def SaveProject(self):
        if self.fileparts.filename == '':
            return
        filename = self.fileparts.AbsoluteFilePath(
        ) + '/' + self.fileparts.FileNameWithExtension(ext='.si')
        self.SaveProjectToFile(filename)

    def config(self, cursor=None):
        pass

    def CalculateSParameters(self):
        netList = self.Drawing.schematic.NetList().Text()
        import SignalIntegrity.Lib as si
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle()
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        spnp = si.p.SystemSParametersNumericParser(
            si.fd.EvenlySpacedFrequencyList(
                SignalIntegrity.App.
                Project['CalculationProperties.EndFrequency'], SignalIntegrity.
                App.Project['CalculationProperties.FrequencyPoints']),
            cacheFileName=cacheFileName)
        spnp.AddLines(netList)
        try:
            sp = spnp.SParameters()
        except si.SignalIntegrityException as e:
            return None
        return (sp,
                self.fileparts.FullFilePathExtension('s' + str(sp.m_P) + 'p'))

    def Simulate(self):
        netList = self.Drawing.schematic.NetList()
        netListText = netList.Text()
        import SignalIntegrity.Lib as si
        fd = si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints'])
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle()
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        snp = si.p.SimulatorNumericParser(fd, cacheFileName=cacheFileName)
        snp.AddLines(netListText)
        try:
            transferMatrices = snp.TransferMatrices()
        except si.SignalIntegrityException as e:
            return None

        outputWaveformLabels = netList.OutputNames()

        try:
            inputWaveformList = self.Drawing.schematic.InputWaveforms()
            sourceNames = netList.SourceNames()
        except si.SignalIntegrityException as e:
            return None

        transferMatricesProcessor = si.td.f.TransferMatricesProcessor(
            transferMatrices)
        si.td.wf.Waveform.adaptionStrategy = 'SinX' if SignalIntegrity.App.Preferences[
            'Calculation.UseSinX'] else 'Linear'

        try:
            outputWaveformList = transferMatricesProcessor.ProcessWaveforms(
                inputWaveformList)
        except si.SignalIntegrityException as e:
            return None

        for outputWaveformIndex in range(len(outputWaveformList)):
            outputWaveform = outputWaveformList[outputWaveformIndex]
            outputWaveformLabel = outputWaveformLabels[outputWaveformIndex]
            for device in self.Drawing.schematic.deviceList:
                if device['partname'].GetValue() in [
                        'Output', 'DifferentialVoltageOutput', 'CurrentOutput'
                ]:
                    if device['ref'].GetValue() == outputWaveformLabel:
                        # probes may have different kinds of gain specified
                        gainProperty = device['gain']
                        gain = gainProperty.GetValue()
                        offset = device['offset'].GetValue()
                        delay = device['td'].GetValue()
                        if gain != 1.0 or offset != 0.0 or delay != 0.0:
                            outputWaveform = outputWaveform.DelayBy(
                                delay) * gain + offset
                        outputWaveformList[
                            outputWaveformIndex] = outputWaveform
                        break
        userSampleRate = SignalIntegrity.App.Project[
            'CalculationProperties.UserSampleRate']
        outputWaveformList = [
            wf.Adapt(
                si.td.wf.TimeDescriptor(
                    wf.td.H, int(wf.td.K * userSampleRate / wf.td.Fs),
                    userSampleRate)) for wf in outputWaveformList
        ]
        return (sourceNames, outputWaveformLabels, transferMatrices,
                outputWaveformList)

    def VirtualProbe(self):
        netList = self.Drawing.schematic.NetList()
        netListText = netList.Text()
        import SignalIntegrity.Lib as si
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle()
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        snp = si.p.VirtualProbeNumericParser(si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints']),
                                             cacheFileName=cacheFileName)
        snp.AddLines(netListText)
        try:
            transferMatrices = snp.TransferMatrices()
        except si.SignalIntegrityException as e:
            return None

        transferMatricesProcessor = si.td.f.TransferMatricesProcessor(
            transferMatrices)
        si.td.wf.Waveform.adaptionStrategy = 'SinX' if SignalIntegrity.App.Preferences[
            'Calculation.UseSinX'] else 'Linear'

        try:
            inputWaveformList = self.Drawing.schematic.InputWaveforms()
            sourceNames = netList.MeasureNames()
        except si.SignalIntegrityException as e:
            return None

        try:
            outputWaveformList = transferMatricesProcessor.ProcessWaveforms(
                inputWaveformList)
        except si.SignalIntegrityException as e:
            return None

        outputWaveformLabels = netList.OutputNames()

        for outputWaveformIndex in range(len(outputWaveformList)):
            outputWaveform = outputWaveformList[outputWaveformIndex]
            outputWaveformLabel = outputWaveformLabels[outputWaveformIndex]
            for device in self.Drawing.schematic.deviceList:
                if device['partname'].GetValue() in [
                        'Output', 'DifferentialVoltageOutput', 'CurrentOutput'
                ]:
                    if device['ref'].GetValue() == outputWaveformLabel:
                        # probes may have different kinds of gain specified
                        gainProperty = device['gain']
                        gain = gainProperty.GetValue()
                        offset = device['offset'].GetValue()
                        delay = device['td'].GetValue()
                        if gain != 1.0 or offset != 0.0 or delay != 0.0:
                            outputWaveform = outputWaveform.DelayBy(
                                delay) * gain + offset
                        outputWaveformList[
                            outputWaveformIndex] = outputWaveform
                        break
        userSampleRate = SignalIntegrity.App.Project[
            'CalculationProperties.UserSampleRate']
        outputWaveformList = [
            wf.Adapt(
                si.td.wf.TimeDescriptor(
                    wf.td.H, int(wf.td.K * userSampleRate / wf.td.Fs),
                    userSampleRate)) for wf in outputWaveformList
        ]
        return (sourceNames, outputWaveformLabels, transferMatrices,
                outputWaveformList)

    def Deembed(self):
        netList = self.Drawing.schematic.NetList().Text()
        import SignalIntegrity.Lib as si
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle()
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        dnp = si.p.DeembedderNumericParser(si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints']),
                                           cacheFileName=cacheFileName)
        dnp.AddLines(netList)

        try:
            sp = dnp.Deembed()
        except si.SignalIntegrityException as e:
            return None

        unknownNames = dnp.m_sd.UnknownNames()
        if len(unknownNames) == 1:
            sp = [sp]

        return (unknownNames, sp)

        filename = []
        for u in range(len(unknownNames)):
            extension = '.s' + str(sp[u].m_P) + 'p'
            filename = unknownNames[u] + extension
            if self.fileparts.filename != '':
                filename.append(self.fileparts.filename + '_' + filename)
        return (unknownNames, sp, filename)
    def Simulate(self, SParameters=False):
        """
        simulates with a network analyzer model
        """
        #
        # the first step is to calculate the s-parameters of a DUT connected to the ports
        # of the network analyzer.
        #
        self.parent.Drawing.stateMachine.Nothing()
        netList = self.parent.Drawing.schematic.NetList().Text()
        import SignalIntegrity.Lib as si
        fd = si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints'])
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.parent.fileparts.FileNameTitle(
            ) + '_DUTSParameters'
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        spnp = si.p.DUTSParametersNumericParser(fd,
                                                cacheFileName=cacheFileName)
        spnp.AddLines(netList)
        progressDialog = ProgressDialog(self.parent,
                                        "Calculating DUT S-parameters",
                                        spnp,
                                        spnp.SParameters,
                                        granularity=1.0)
        try:
            (DUTSp, NetworkAnalyzerProjectFile) = progressDialog.GetResult()
            showDutsp = False
            if showDutsp:
                from SignalIntegrity.App.SParameterViewerWindow import SParametersDialog
                self.spd = self.spd = SParametersDialog(
                    self.parent,
                    DUTSp,
                    filename=self.parent.fileparts.FullFilePathExtension(
                        's' + str(DUTSp.m_P) + 'p'))
        except si.SignalIntegrityException as e:
            messagebox.showerror('DUT S-parameter Calculator',
                                 e.parameter + ': ' + e.message)
            return None
        #
        # DUTSp now contains the s-parameters of the DUT.  The DUT has a number of ports dictated by how many ports were actually connected
        # to the network analzyer, and the port connections are in spnp.NetworkAnalyzerPortConnectionList
        #
        # The next step is to get the netlist from the network analyzer model's project
        #
        netListText = None
        if NetworkAnalyzerProjectFile != None:
            level = SignalIntegrityAppHeadless.projectStack.Push()
            try:
                app = SignalIntegrityAppHeadless()
                if app.OpenProjectFile(
                        os.path.realpath(NetworkAnalyzerProjectFile)):
                    app.Drawing.DrawSchematic()
                    netList = app.Drawing.schematic.NetList()
                    netListText = netList.Text()
                else:
                    raise SignalIntegrityExceptionNetworkAnalyzer(
                        'file could not be opened: ' +
                        NetworkAnalyzerProjectFile)
            except SignalIntegrityException as e:
                messagebox.showerror('Network Analyzer Model: ',
                                     e.parameter + ': ' + e.message)
            finally:
                SignalIntegrityAppHeadless.projectStack.Pull(level)
        else:
            netList = self.parent.Drawing.schematic.NetList()
            netListText = self.parent.NetListText()
        if netListText == None:
            return
        #
        # Now, with the dut s-parameters and the netlist of the network analyzer model, get the transfer matrices for a simulation with the DUT
        # using the network analyzer model.
        #
        cacheFileName = self.parent.fileparts.FileNameTitle(
        ) + '_TransferMatrices' if SignalIntegrity.App.Preferences[
            'Cache.CacheResults'] else None
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        snp = si.p.NetworkAnalyzerSimulationNumericParser(
            fd,
            DUTSp,
            spnp.NetworkAnalyzerPortConnectionList,
            cacheFileName=cacheFileName)
        snp.AddLines(netListText)
        progressDialog = ProgressDialog(self.parent,
                                        "Calculating Transfer Matrices",
                                        snp,
                                        snp.TransferMatrices,
                                        granularity=1.0)
        level = SignalIntegrityAppHeadless.projectStack.Push()
        try:
            os.chdir(
                FileParts(os.path.abspath(
                    NetworkAnalyzerProjectFile)).AbsoluteFilePath())
            self.transferMatrices = progressDialog.GetResult()
        except si.SignalIntegrityException as e:
            messagebox.showerror('Transfer Matrices Calculation: ',
                                 e.parameter + ': ' + e.message)
            return None
        finally:
            SignalIntegrityAppHeadless.projectStack.Pull(level)
        self.sourceNames = snp.m_sd.SourceVector()
        #
        # to clear up any confusion, if the DUT was not connected to all of the network analyzer ports, a multi-port DUT with
        # opens on the unconnected ports was constructed and connected as the DUT, but it was remembered which network
        # analyzer ports are actually driven.  The driven ports, in order, are the first names in self.sourceNames with
        # snp.simulationNumPorts containing the number of them.
        #
        # In other words, if a single-port reflect calibration is performed on port 2 of the network analyzer, a two-port
        # DUT was installed, with an open on port 1, and the transfer parameters were computed for only the outputs needed
        # (the superfluous probe outputs were removed).  self.sourceNames would contain only the reference designator for
        # the transmitter that is on port 2, followed by any other waveforms supplied to the system (usuaully noise).
        #
        # Now, we loop over all of the transmitters that are driven and create a list of lists, where each element in the list
        # is a list of input waveforms to be used in the simulation under that driven condition.  We do this by first, setting
        # all of the transmitters in the appropriate on/off state, and then gathering all of the waveforms.
        #
        gdoDict = {}
        self.wflist = []
        if NetworkAnalyzerProjectFile != None:
            level = SignalIntegrityAppHeadless.projectStack.Push()
            try:
                app = SignalIntegrityAppHeadless()
                if app.OpenProjectFile(
                        os.path.realpath(NetworkAnalyzerProjectFile)):
                    app.Drawing.DrawSchematic()
                    # get output gain, offset, delay
                    for name in [rdn[2] for rdn in snp.m_sd.pOutputList]:
                        gdoDict[name] = {
                            'gain': float(app.Device(name)['gain']['Value']),
                            'offset':
                            float(app.Device(name)['offset']['Value']),
                            'delay': float(app.Device(name)['td']['Value'])
                        }
                    for driven in range(snp.simulationNumPorts):
                        for port in range(snp.simulationNumPorts):
                            app.Device(self.sourceNames[port])['state'][
                                'Value'] = 'on' if port == driven else 'off'
                        self.wflist.append([
                            app.Device(self.sourceNames[wfIndex]).Waveform()
                            for wfIndex in range(len(self.sourceNames))
                        ])
                else:
                    raise SignalIntegrityExceptionNetworkAnalyzer(
                        'file could not be opened: ' +
                        NetworkAnalyzerProjectFile)
            except SignalIntegrityException as e:
                messagebox.showerror('Network Analyzer Model: ',
                                     e.parameter + ': ' + e.message)
            finally:
                SignalIntegrityAppHeadless.projectStack.Pull(level)
        else:
            # since we're modifying the current schematic, keep the state for restoring
            stateList = [
                app.Device(self.sourceNames[port])['state']['Value']
                for port in range(snp.simulationNumPorts)
            ]
            for name in [rdn[2] for rdn in snp.m_sd.pOutputList]:
                gdoDict[name] = {
                    'gain': float(app.Device()[name]['gain']['Value']),
                    'offset': float(app.Device()[name]['offset']['Value']),
                    'delay': float(app.Device()[name]['td']['Value'])
                }
            for driven in range(snp.simulationNumPorts):
                for port in range(snp.simulationNumPorts):
                    app.Device(
                        self.sourceNames[port]
                    )['state']['Value'] = 'on' if port == driven else 'off'
                self.wflist.append([
                    app.Device(self.sourceNames[wfIndex]).Waveform()
                    for wfIndex in range(len(self.sourceNames))
                ])
            # restore the states
            for port in range(snp.simulationNumPorts):
                app.Device(
                    self.sourceNames[port])['state']['Value'] = stateList[port]
        #
        # Now, the list of list of input waveforms are processed, generating a list of list of output waveforms in
        # self.outputwflist.
        #
        self.transferMatriceProcessor = si.td.f.TransferMatricesProcessor(
            self.transferMatrices)
        si.td.wf.Waveform.adaptionStrategy = 'SinX' if SignalIntegrity.App.Preferences[
            'Calculation.UseSinX'] else 'Linear'
        progressDialog = ProgressDialog(self.parent, "Waveform Processing",
                                        self.transferMatriceProcessor,
                                        self._ProcessWaveforms)
        try:
            outputWaveformList = progressDialog.GetResult()
        except si.SignalIntegrityException as e:
            messagebox.showerror('Simulator', e.parameter + ': ' + e.message)
            return
        #
        # The list of list of input waveforms have been processed processed, generating a list of list of output waveforms in
        # self.outputwflist.  The names of the output waveforms are in snp.m_sd.pOutputList.
        #
        self.outputwflist = [[
            wf.Adapt(
                si.td.wf.TimeDescriptor(wf.td[wf.td.IndexOfTime(-5e-9)],
                                        fd.TimeDescriptor().K, wf.td.Fs))
            for wf in driven
        ] for driven in self.outputwflist]

        # The port connection list, which is a list of True or False for each port on the network analyzer, is
        # converted to a list of network port indices corresponding to the driven ports.
        #
        portConnections = []
        for pci in range(len(snp.PortConnectionList)):
            if snp.PortConnectionList[pci]: portConnections.append(pci)

        # Here, the output waveforms are refined by applying any probe gain, offset, and delay, and the
        # waveform labels are converted to a list of list of waveform labels, with the driven port appended.
        outputWaveformList = []
        self.outputWaveformLabels = []
        for r in range(len(self.outputwflist)):
            wflist = self.outputwflist[r]
            for c in range(len(wflist)):
                wf = wflist[c]
                wfName = snp.m_sd.pOutputList[c][2]
                gain = gdoDict[wfName]['gain']
                offset = gdoDict[wfName]['offset']
                delay = gdoDict[wfName]['delay']
                if gain != 1.0 or offset != 0.0 or delay != 0.0:
                    wf = wf.DelayBy(delay) * gain + offset
                outputWaveformList.append(wf)
                self.outputWaveformLabels.append(wfName +
                                                 str(portConnections[r] + 1))

        userSampleRate = SignalIntegrity.App.Project[
            'CalculationProperties.UserSampleRate']
        outputWaveformList = [
            wf.Adapt(
                si.td.wf.TimeDescriptor(
                    wf.td.H, int(wf.td.K * userSampleRate / wf.td.Fs),
                    userSampleRate)) for wf in outputWaveformList
        ]

        td = si.td.wf.TimeDescriptor(
            -5e-9,
            SignalIntegrity.App.Project['CalculationProperties.TimePoints'],
            SignalIntegrity.App.Project['CalculationProperties.BaseSampleRate']
        )
        frequencyList = td.FrequencyList()

        if snp.simulationType != 'CW':
            # note this matrix is transposed from what is normally expected
            Vmat = [[
                outputWaveformList[self.outputWaveformLabels.index(
                    'V' + str(portConnections[r] + 1) +
                    str(portConnections[c] + 1))]
                for r in range(len(portConnections))
            ] for c in range(len(portConnections))]

            for vli in range(len(Vmat)):
                tdr = si.m.tdr.TDRWaveformToSParameterConverter(
                    WindowForwardHalfWidthTime=500e-12,
                    WindowReverseHalfWidthTime=500e-12,
                    WindowRaisedCosineDuration=250e-12,
                    Step=(snp.simulationType == 'TDRStep'),
                    Length=0,
                    Denoise=(snp.simulationType != 'TDRStep'),
                    DenoisePercent=20.,
                    Inverted=False,
                    fd=frequencyList)

                tdr.Convert(Vmat[vli], vli)
                for r in range(len(portConnections)):
                    outputWaveformList.append(tdr.IncidentWaveform if r ==
                                              vli else si.td.wf.Waveform(td))
                    self.outputWaveformLabels.append(
                        'A' + str(portConnections[r] + 1) +
                        str(portConnections[vli] + 1))
                for r in range(len(portConnections)):
                    outputWaveformList.append(tdr.ReflectWaveforms[r])
                    self.outputWaveformLabels.append(
                        'B' + str(portConnections[r] + 1) +
                        str(portConnections[vli] + 1))

        if not SParameters:
            self.SimulatorDialog().title('Sim: ' +
                                         self.parent.fileparts.FileNameTitle())
            self.SimulatorDialog().ExamineTransferMatricesDoer.Activate(True)
            self.SimulatorDialog().SimulateDoer.Activate(True)
            self.SimulatorDialog().ViewTimeDomainDoer.Set(
                snp.simulationType != 'CW')
            self.SimulatorDialog().ViewTimeDomainDoer.Activate(
                snp.simulationType != 'CW')
            self.SimulatorDialog().ViewSpectralContentDoer.Set(
                snp.simulationType == 'CW')
            self.SimulatorDialog().ViewSpectralDensityDoer.Set(False)
            self.UpdateWaveforms(outputWaveformList, self.outputWaveformLabels)
        else:
            frequencyContentList = [
                wf.FrequencyContent(fd) for wf in outputWaveformList
            ]

            Afc = [[
                frequencyContentList[self.outputWaveformLabels.index(
                    'A' + str(portConnections[r] + 1) +
                    str(portConnections[c] + 1))]
                for c in range(len(portConnections))
            ] for r in range(len(portConnections))]
            Bfc = [[
                frequencyContentList[self.outputWaveformLabels.index(
                    'B' + str(portConnections[r] + 1) +
                    str(portConnections[c] + 1))]
                for c in range(len(portConnections))
            ] for r in range(len(portConnections))]

            from numpy import matrix

            data = [None for _ in range(len(frequencyList))]
            for n in range(len(frequencyList)):
                B = [[Bfc[r][c][n] for c in range(snp.simulationNumPorts)]
                     for r in range(snp.simulationNumPorts)]
                A = [[Afc[r][c][n] for c in range(snp.simulationNumPorts)]
                     for r in range(snp.simulationNumPorts)]
                data[n] = (matrix(B) * matrix(A).getI()).tolist()
            sp = si.sp.SParameters(frequencyList, data)
            return sp
Example #12
0
def ProjectModificationTime(modificationTimeDict, fileName):
    #print(os.path.abspath(fileName))
    if modificationTimeDict == None:
        return None
    if os.path.abspath(fileName) in [
            file['name'] for file in modificationTimeDict
    ]:
        if modificationTimeDict[[
                file['name'] for file in modificationTimeDict
        ].index(os.path.abspath(fileName))]['traversed'] == False:
            # this is a recursion problem
            return None
        else:
            return (modificationTimeDict)
    elif not fileName.endswith('.si'):
        modificationTimeDict.append({
            'name':
            os.path.abspath(fileName),
            'time':
            os.path.getmtime(os.path.abspath(fileName)),
            'traversed':
            True
        })
    else:
        modificationTimeDict.append({
            'name':
            os.path.abspath(fileName),
            'time':
            os.path.getmtime(os.path.abspath(fileName)),
            'traversed':
            False
        })
        filenamenoext = FileParts(fileName).FileNameTitle()
        for postfix in ['', '_DUTSParameters', '_TransferMatrices']:
            for cacheName in [
                    'SParameters', 'TransferMatrices', 'Calibration'
            ]:
                cacheFileName = FileParts(filenamenoext + postfix + '_cached' +
                                          cacheName).FileNameWithExtension(
                                              '.p')
                if os.path.exists(cacheFileName):
                    modificationTimeDict = ProjectModificationTime(
                        modificationTimeDict, cacheFileName)
        level = SignalIntegrityAppHeadless.projectStack.Push()
        result = 0
        try:
            app = SignalIntegrityAppHeadless()
            if not app.OpenProjectFile(os.path.realpath(fileName)):
                raise ValueError
            app.Drawing.DrawSchematic()
            if not app.Drawing.canCalculate:
                raise ValueError
            deviceList = app.Drawing.schematic.deviceList
            for device in deviceList:
                propertiesList = device.propertiesList
                for property in propertiesList:
                    if property['Type'] == 'file':
                        filename = property['Value']
                        if filename.endswith('.si'):
                            modificationTimeDict = ProjectModificationTime(
                                modificationTimeDict, filename)
                            filenamenoext = FileParts(filename).FileNameTitle()
                            for postfix in [
                                    '', '_DUTSParameters', '_TransferMatrices'
                            ]:
                                for cacheName in [
                                        'SParameters', 'TransferMatrices',
                                        'Calibration'
                                ]:
                                    cacheFileName = FileParts(
                                        filenamenoext + postfix + '_cached' +
                                        cacheName).FileNameWithExtension('.p')
                                    if os.path.exists(cacheFileName):
                                        modificationTimeDict = ProjectModificationTime(
                                            modificationTimeDict,
                                            cacheFileName)
                        else:
                            if '.' in filename:
                                modificationTimeDict.append({
                                    'name':
                                    os.path.abspath(filename),
                                    'time':
                                    os.path.getmtime(
                                        os.path.abspath(filename)),
                                    'traversed':
                                    True
                                })
                        if modificationTimeDict == None:
                            raise ValueError
        except:
            result = None
        SignalIntegrityAppHeadless.projectStack.Pull(level)
        if result == None:
            return result
    modificationTimeDict[[file['name'] for file in modificationTimeDict].index(
        os.path.abspath(fileName))]['traversed'] = True
    return modificationTimeDict
Example #13
0
    def SimulateNetworkAnalyzerModel(self, SParameters=False):
        netList = self.Drawing.schematic.NetList().Text()
        import SignalIntegrity.Lib as si
        fd = si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints'])
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle() + '_DUTSParameters'
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        spnp = si.p.DUTSParametersNumericParser(fd,
                                                cacheFileName=cacheFileName)
        spnp.AddLines(netList)
        try:
            (DUTSp, NetworkAnalyzerProjectFile) = spnp.SParameters()
        except si.SignalIntegrityException as e:
            return None
        netListText = None
        if NetworkAnalyzerProjectFile != None:
            level = SignalIntegrityAppHeadless.projectStack.Push()
            try:
                app = SignalIntegrityAppHeadless()
                if app.OpenProjectFile(
                        os.path.realpath(NetworkAnalyzerProjectFile)):
                    app.Drawing.DrawSchematic()
                    netList = app.Drawing.schematic.NetList()
                    netListText = netList.Text()
                else:
                    pass
            except:
                pass
            finally:
                SignalIntegrityAppHeadless.projectStack.Pull(level)
        else:
            netList = self.Drawing.schematic.NetList()
            netListText = self.NetListText()

        if netListText == None:
            return None
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle(
            ) + '_TransferMatrices'
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        snp = si.p.NetworkAnalyzerSimulationNumericParser(
            fd,
            DUTSp,
            spnp.NetworkAnalyzerPortConnectionList,
            cacheFileName=cacheFileName)
        snp.AddLines(netListText)
        level = SignalIntegrityAppHeadless.projectStack.Push()
        try:
            os.chdir(
                FileParts(os.path.abspath(
                    NetworkAnalyzerProjectFile)).AbsoluteFilePath())
            transferMatrices = snp.TransferMatrices()
        except si.SignalIntegrityException as e:
            return None
        finally:
            SignalIntegrityAppHeadless.projectStack.Pull(level)

        sourceNames = snp.m_sd.SourceVector()

        gdoDict = {}

        if NetworkAnalyzerProjectFile != None:
            level = SignalIntegrityAppHeadless.projectStack.Push()
            try:
                app = SignalIntegrityAppHeadless()
                if app.OpenProjectFile(
                        os.path.realpath(NetworkAnalyzerProjectFile)):
                    app.Drawing.DrawSchematic()
                    # get output gain, offset, delay
                    for name in [rdn[2] for rdn in snp.m_sd.pOutputList]:
                        gdoDict[name] = {
                            'gain': float(app.Device(name)['gain']['Value']),
                            'offset':
                            float(app.Device(name)['offset']['Value']),
                            'delay': float(app.Device(name)['td']['Value'])
                        }
                    stateList = [
                        app.Device(sourceNames[port])['state']['Value']
                        for port in range(snp.simulationNumPorts)
                    ]
                    self.wflist = []
                    for driven in range(snp.simulationNumPorts):
                        thiswflist = []
                        for port in range(snp.simulationNumPorts):
                            app.Device(sourceNames[port])['state'][
                                'Value'] = 'on' if port == driven else 'off'
                        for wfIndex in range(len(sourceNames)):
                            thiswflist.append(
                                app.Device(sourceNames[wfIndex]).Waveform())
                        self.wflist.append(thiswflist)
                    for port in range(snp.simulationNumPorts):
                        app.Device(sourceNames[port]
                                   )['state']['Value'] = stateList[port]
                else:
                    pass
            except:
                pass
            finally:
                SignalIntegrityAppHeadless.projectStack.Pull(level)
        else:
            stateList = [
                app.Device(sourceNames[port])['state']['Value']
                for port in range(snp.simulationNumPorts)
            ]
            self.wflist = []
            for name in [rdn[2] for rdn in snp.m_sd.pOutputList]:
                gdoDict[name] = {
                    'gain': float(app.Device()[name]['gain']['Value']),
                    'offset': float(app.Device()[name]['offset']['Value']),
                    'delay': float(app.Device()[name]['td']['Value'])
                }
            for driven in range(snp.simulationNumPorts):
                thiswflist = []
                for port in range(snp.simulationNumPorts):
                    app.Device(
                        sourceNames[port]
                    )['state']['Value'] = 'on' if port == driven else 'off'
                for wfIndex in range(len(sourceNames)):
                    thiswflist.append(
                        app.Device(sourceNames[wfIndex]).Waveform())
                self.wflist.append(thiswflist)
            for port in range(snp.simulationNumPorts):
                app.Device(
                    sourceNames[port])['state']['Value'] = stateList[port]

        self.transferMatriceProcessor = si.td.f.TransferMatricesProcessor(
            transferMatrices)
        si.td.wf.Waveform.adaptionStrategy = 'SinX' if SignalIntegrity.App.Preferences[
            'Calculation.UseSinX'] else 'Linear'

        try:
            outputwflist = []
            for port in range(len(self.wflist)):
                outputwflist.append(
                    self.transferMatriceProcessor.ProcessWaveforms(
                        self.wflist[port], adaptToLargest=True))
        except si.SignalIntegrityException as e:
            return None
        #
        # The list of list of input waveforms have been processed processed, generating a list of list of output waveforms in
        # self.outputwflist.  The names of the output waveforms are in snp.m_sd.pOutputList.
        #
        outputwflist = [[
            wf.Adapt(
                si.td.wf.TimeDescriptor(wf.td[wf.td.IndexOfTime(-5e-9)],
                                        fd.TimeDescriptor().K, wf.td.Fs))
            for wf in driven
        ] for driven in outputwflist]

        # The port connection list, which is a list of True or False for each port on the network analyzer, is
        # converted to a list of network port indices corresponding to the driven ports.
        #
        portConnections = []
        for pci in range(len(snp.PortConnectionList)):
            if snp.PortConnectionList[pci]: portConnections.append(pci)

        outputWaveformList = []
        outputWaveformLabels = []
        for r in range(len(outputwflist)):
            wflist = outputwflist[r]
            for c in range(len(wflist)):
                wf = wflist[c]
                wfName = snp.m_sd.pOutputList[c][2]
                gain = gdoDict[wfName]['gain']
                offset = gdoDict[wfName]['offset']
                delay = gdoDict[wfName]['delay']
                if gain != 1.0 or offset != 0.0 or delay != 0.0:
                    wf = wf.DelayBy(delay) * gain + offset
                outputWaveformList.append(wf)
                outputWaveformLabels.append(snp.m_sd.pOutputList[c][2] +
                                            str(portConnections[r] + 1))

        userSampleRate = SignalIntegrity.App.Project[
            'CalculationProperties.UserSampleRate']
        outputWaveformList = [
            wf.Adapt(
                si.td.wf.TimeDescriptor(
                    wf.td.H, int(wf.td.K * userSampleRate / wf.td.Fs),
                    userSampleRate)) for wf in outputWaveformList
        ]

        td = si.td.wf.TimeDescriptor(
            -5e-9,
            SignalIntegrity.App.Project['CalculationProperties.TimePoints'],
            SignalIntegrity.App.Project['CalculationProperties.BaseSampleRate']
        )

        if snp.simulationType != 'CW':
            # note this matrix is transposed from what is normally expected
            Vmat = [[
                outputWaveformList[outputWaveformLabels.index(
                    'V' + str(portConnections[r] + 1) +
                    str(portConnections[c] + 1))]
                for r in range(len(portConnections))
            ] for c in range(len(portConnections))]

            for vli in range(len(Vmat)):
                tdr = si.m.tdr.TDRWaveformToSParameterConverter(
                    WindowForwardHalfWidthTime=200e-12,
                    WindowReverseHalfWidthTime=200e-12,
                    WindowRaisedCosineDuration=50e-12,
                    Step=(snp.simulationType == 'TDRStep'),
                    Length=0,
                    Denoise=True,
                    DenoisePercent=20.,
                    Inverted=False,
                    fd=td.FrequencyList())

                tdr.Convert(Vmat[vli], vli)
                for r in range(len(portConnections)):
                    outputWaveformList.append(tdr.IncidentWaveform if r ==
                                              vli else si.td.wf.Waveform(td))
                    outputWaveformLabels.append('A' +
                                                str(portConnections[r] + 1) +
                                                str(portConnections[vli] + 1))
                for r in range(len(portConnections)):
                    outputWaveformList.append(tdr.ReflectWaveforms[r])
                    outputWaveformLabels.append('B' +
                                                str(portConnections[r] + 1) +
                                                str(portConnections[vli] + 1))

        if not SParameters:
            return (sourceNames, outputWaveformLabels, transferMatrices,
                    outputWaveformList)
        else:
            # waveforms are adapted this way to give the horizontal offset that it already has closest to
            #-5 ns, with the correct number of points without resampling the waveform in any way.
            frequencyContentList = []
            for wf in outputWaveformList:
                td = si.td.wf.TimeDescriptor(
                    -5e-9, SignalIntegrity.App.
                    Project['CalculationProperties.TimePoints'],
                    SignalIntegrity.App.
                    Project['CalculationProperties.BaseSampleRate'])
                td.H = wf.TimeDescriptor()[wf.TimeDescriptor().IndexOfTime(
                    td.H)]
                fc = wf.Adapt(td).FrequencyContent()
                frequencyContentList.append(fc)

            Afc = [[
                frequencyContentList[outputWaveformLabels.index(
                    'A' + str(portConnections[r] + 1) +
                    str(portConnections[c] + 1))]
                for c in range(len(portConnections))
            ] for r in range(len(portConnections))]
            Bfc = [[
                frequencyContentList[outputWaveformLabels.index(
                    'B' + str(portConnections[r] + 1) +
                    str(portConnections[c] + 1))]
                for c in range(len(portConnections))
            ] for r in range(len(portConnections))]

            from numpy import array
            from numpy.linalg import inv

            frequencyList = td.FrequencyList()
            data = [None for _ in range(len(frequencyList))]
            for n in range(len(frequencyList)):
                B = [[Bfc[r][c][n] for c in range(snp.simulationNumPorts)]
                     for r in range(snp.simulationNumPorts)]
                A = [[Afc[r][c][n] for c in range(snp.simulationNumPorts)]
                     for r in range(snp.simulationNumPorts)]
                data[n] = (array(B).dot(inv(array(A)))).tolist()
            sp = si.sp.SParameters(frequencyList, data)
            return sp
    def onFileView(self):
        self.parentFrame.focus()
        filename = self.partProperty.GetValue()
        if filename != '':
            import SignalIntegrity.Lib as si
            if FileParts(filename).fileext == '.si':
                result = os.system('SignalIntegrity "' +
                                   os.path.abspath(filename) + '" --external')
                if result != 0:
                    messagebox.showerror('ProjectFile', 'could not be opened')
                    return
            elif self.partProperty['PropertyName'] == 'filename':
                try:
                    sp = si.sp.SParameterFile(filename)
                except si.SignalIntegrityException as e:
                    messagebox.showerror('S-parameter Viewer',
                                         e.parameter + ': ' + e.message)
                    return
                spd = SParametersDialog(self.parent.parent.parent, sp,
                                        filename)
                try:
                    spd.grab_set()
                    spd.focus_set()
                    import platform
                    thisOS = platform.system()
                    if thisOS == 'Linux':
                        spd.attributes('-type', 'dialog')
                    elif thisOS == 'Windows':
                        spd.attributes('-toolwindow', True)

                    def disable_event():
                        pass

                    self.parent.parent.protocol("WM_DELETE_WINDOW",
                                                disable_event)
                    spd.attributes('-topmost', 1)
                    #                     spd.transient(self.parent.parent)
                    self.wait_window(spd)
                finally:
                    self.parent.parent.protocol("WM_DELETE_WINDOW",
                                                self.parent.parent.cancel)
            elif self.partProperty['PropertyName'] == 'waveformfilename':
                filenametoshow = ('/'.join(
                    filename.split('\\'))).split('/')[-1]
                if filenametoshow is None:
                    filenametoshow = ''
                try:
                    wf = self.parent.device.Waveform()
                except si.SignalIntegrityException as e:
                    messagebox.showerror('Waveform Viewer',
                                         e.parameter + ': ' + e.message)
                    return
                sd = SimulatorDialog(self.parent.parent)
                sd.title(filenametoshow)
                sd.UpdateWaveforms([wf], [filenametoshow])
                sd.state('normal')
                try:
                    import platform
                    thisOS = platform.system()
                    if thisOS == 'Linux':
                        sd.attributes('-type', 'dialog')
                    elif thisOS == 'Windows':
                        sd.attributes('-toolwindow', True)

                    def disable_event():
                        pass

                    self.parent.parent.protocol("WM_DELETE_WINDOW",
                                                disable_event)
                    sd.attributes('-topmost', 1)
                    sd.focus_set()
                    sd.grab_set()
                    #                     sd.transient(self.parent.parent)
                    self.wait_window(sd)
                finally:
                    self.parent.parent.protocol("WM_DELETE_WINDOW",
                                                self.parent.parent.cancel)

            elif self.partProperty['PropertyName'] == 'errorterms':
                calibration = self.parent.parent.parent.OpenCalibrationFile(
                    os.path.abspath(filename))
                if calibration is None:
                    messagebox.showerror('Calibration File',
                                         'could not be opened')
                    return
                else:
                    self.parent.parent.parent.ViewCalibration(calibration)
Example #15
0
    def __init__(self, parent,sp,filename=None,title=None,buttonLabels=None):
        tk.Toplevel.__init__(self, parent)
        self.parent=parent
        self.withdraw()
        self.fileparts=FileParts(filename)
        if title is None:
            if self.fileparts.filename =='':
                self.title('S-parameters')
            else:
                self.title('S-parameters: '+self.fileparts.FileNameTitle())
        else:
            if filename is None:
                self.title(title)
            else:
                self.title(title+': '+self.fileparts.FileNameTitle())

        img = tk.PhotoImage(file=SignalIntegrity.App.IconsBaseDir+'AppIcon2.gif')
        self.tk.call('wm', 'iconphoto', self._w, img)
        self.protocol("WM_DELETE_WINDOW", self.onClosing)

        self.variableLineWidth = tk.BooleanVar()
        self.showPassivityViolations = tk.BooleanVar()
        self.showCausalityViolations = tk.BooleanVar()
        self.showImpedance = tk.BooleanVar()
        self.logScale =  tk.BooleanVar()

        # the Doers - the holder of the commands, menu elements, toolbar elements, and key bindings
        self.ReadSParametersFromFileDoer = Doer(self.onReadSParametersFromFile).AddKeyBindElement(self,'<Control-o>').AddHelpElement('Control-Help:Open-S-parameter-File')
        self.WriteSParametersToFileDoer = Doer(self.onWriteSParametersToFile).AddKeyBindElement(self,'<Control-s>').AddHelpElement('Control-Help:Save-S-parameter-File')
        self.Matplotlib2tikzDoer = Doer(self.onMatplotlib2TikZ)
        # ------
        self.CalculationPropertiesDoer = Doer(self.onCalculationProperties).AddHelpElement('Control-Help:Calculation-Properties')
        self.ResampleDoer = Doer(self.onResample).AddHelpElement('Control-Help:Resample')
        self.EnforcePassivityDoer = Doer(self.onEnforcePassivity).AddHelpElement('Control-Help:Enforce-Passivity')
        self.EnforceCausalityDoer = Doer(self.onEnforceCausality).AddHelpElement('Control-Help:Enforce-Causality')
        self.WaveletDenoiseDoer = Doer(self.onWaveletDenoise).AddHelpElement('Control-Help:Wavelet-Denoise')
        # ------
        self.HelpDoer = Doer(self.onHelp).AddHelpElement('Control-Help:Open-Help-File')
        self.ControlHelpDoer = Doer(self.onControlHelp).AddHelpElement('Control-Help:Control-Help')
        # ------
        self.VariableLineWidthDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Variable-Line-Width')
        self.ShowPassivityViolationsDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Show-Passivity-Violations')
        self.ShowCausalityViolationsDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Show-Causality-Violations')
        self.ShowImpedanceDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Show-Impedance')
        self.LogScaleDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Log-Scale')
        # ------
        self.EscapeDoer = Doer(self.onEscape).AddKeyBindElement(self,'<Escape>').DisableHelp()

        # The menu system
        TheMenu=tk.Menu(self)
        self.config(menu=TheMenu)
        # ------
        FileMenu=tk.Menu(self)
        TheMenu.add_cascade(label='File',menu=FileMenu,underline=0)
        self.WriteSParametersToFileDoer.AddMenuElement(FileMenu,label="Save",accelerator='Ctrl+S',underline=0)
        self.ReadSParametersFromFileDoer.AddMenuElement(FileMenu,label="Open File",accelerator='Ctrl+O',underline=0)
        FileMenu.add_separator()
        self.Matplotlib2tikzDoer.AddMenuElement(FileMenu,label='Output to LaTeX (TikZ)',underline=10)
        # ------
        CalcMenu=tk.Menu(self)
        TheMenu.add_cascade(label='Calculate',menu=CalcMenu,underline=0)
        self.CalculationPropertiesDoer.AddMenuElement(CalcMenu,label='Calculation Properties',underline=0)
        #CalcMenu.add_separator()
        self.ResampleDoer.AddMenuElement(CalcMenu,label='Resample',underline=0)
        #CalcMenu.add_separator()
        self.EnforcePassivityDoer.AddMenuElement(CalcMenu,label='Enforce Passivity',underline=8)
        self.EnforceCausalityDoer.AddMenuElement(CalcMenu,label='Enforce Causality',underline=9)
        self.WaveletDenoiseDoer.AddMenuElement(CalcMenu,label='Wavelet Denoise',underline=0)
        # ------
        ViewMenu=tk.Menu(self)
        TheMenu.add_cascade(label='View',menu=ViewMenu,underline=0)
        self.VariableLineWidthDoer.AddCheckButtonMenuElement(ViewMenu,label='Variable Line Width',underline=9,onvalue=True,offvalue=False,variable=self.variableLineWidth)
        self.ShowPassivityViolationsDoer.AddCheckButtonMenuElement(ViewMenu,label='Show Passivity Violations',underline=5,onvalue=True,offvalue=False,variable=self.showPassivityViolations)
        self.ShowCausalityViolationsDoer.AddCheckButtonMenuElement(ViewMenu,label='Show Causality Violations',underline=6,onvalue=True,offvalue=False,variable=self.showCausalityViolations)
        self.ShowImpedanceDoer.AddCheckButtonMenuElement(ViewMenu,label='Show Impedance',underline=5,onvalue=True,offvalue=False,variable=self.showImpedance)
        self.LogScaleDoer.AddCheckButtonMenuElement(ViewMenu,label='Log Scale',underline=4,onvalue=True,offvalue=False,variable=self.logScale)
        # ------
        HelpMenu=tk.Menu(self)
        TheMenu.add_cascade(label='Help',menu=HelpMenu,underline=0)
        self.HelpDoer.AddMenuElement(HelpMenu,label='Open Help File',underline=0)
        self.ControlHelpDoer.AddMenuElement(HelpMenu,label='Control Help',underline=0)

        # The Toolbar
        ToolBarFrame = tk.Frame(self)
        ToolBarFrame.pack(side=tk.TOP,fill=tk.X,expand=tk.NO)
        self.ReadSParametersFromFileDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'document-open-2.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
        self.WriteSParametersToFileDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'document-save-2.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
        tk.Frame(self,bd=2,relief=tk.SUNKEN).pack(side=tk.LEFT,fill=tk.X,padx=5,pady=5)
        self.CalculationPropertiesDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'tooloptions.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
        tk.Frame(ToolBarFrame,height=2,bd=2,relief=tk.RAISED).pack(side=tk.LEFT,fill=tk.X,padx=5,pady=5)
        self.HelpDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'help-contents-5.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
        self.ControlHelpDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'help-3.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)

        topFrame=tk.Frame(self)
        topFrame.pack(side=tk.TOP,fill=tk.BOTH,expand=tk.YES)
        bottomFrame=tk.Frame(self)
        bottomFrame.pack(side=tk.TOP,fill=tk.BOTH,expand=tk.YES)
        topLeftFrame=tk.Frame(topFrame)
        topLeftFrame.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)
        topRightFrame=tk.Frame(topFrame)
        topRightFrame.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)
        bottomLeftFrame=tk.Frame(bottomFrame)
        bottomLeftFrame.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)
        bottomRightFrame=tk.Frame(bottomFrame)
        bottomRightFrame.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)

        self.topLeftFigure=Figure(figsize=(5,2), dpi=100)
        self.topLeftPlot=self.topLeftFigure.add_subplot(111)
        self.topLeftCanvas=FigureCanvasTkAgg(self.topLeftFigure, master=topLeftFrame)
        self.topLeftCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.X, expand=1)
        self.topLeftToolbar = NavigationToolbar2Tk( self.topLeftCanvas, topLeftFrame )
        self.topLeftToolbar.update()
        self.topLeftCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        self.topRightFigure=Figure(figsize=(5,2), dpi=100)
        self.topRightPlot=self.topRightFigure.add_subplot(111)
        self.topRightCanvas=FigureCanvasTkAgg(self.topRightFigure, master=topRightFrame)
        self.topRightCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.X, expand=1)
        self.topRightToolbar = NavigationToolbar2Tk( self.topRightCanvas, topRightFrame )
        self.topRightToolbar.update()
        self.topRightCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.topRightCanvasControlsFrame=tk.Frame(topRightFrame)
        self.topRightCanvasControlsFrame.pack(side=tk.TOP, fill=tk.X, expand=tk.NO)
        tk.Button(self.topRightCanvasControlsFrame,text='unwrap',command=self.onUnwrap).pack(side=tk.LEFT,expand=tk.NO,fill=tk.NONE)
        self.delay=PartPropertyDelay(0.)
        self.delayViewerProperty=ViewerProperty(self.topRightCanvasControlsFrame,self.delay,self.onDelayEntered)

        self.bottomLeftFigure=Figure(figsize=(5,2), dpi=100)
        self.bottomLeftPlot=self.bottomLeftFigure.add_subplot(111)
        self.bottomLeftCanvas=FigureCanvasTkAgg(self.bottomLeftFigure, master=bottomLeftFrame)
        self.bottomLeftCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.X, expand=1)
        self.bottomLeftToolbar = NavigationToolbar2Tk( self.bottomLeftCanvas, bottomLeftFrame )
        self.bottomLeftToolbar.update()
        self.bottomLeftCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        self.bottomRightFigure=Figure(figsize=(5,2), dpi=100)
        self.bottomRightPlot=self.bottomRightFigure.add_subplot(111)
        self.bottomRightCanvas=FigureCanvasTkAgg(self.bottomRightFigure, master=bottomRightFrame)
        self.bottomRightCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.X, expand=1)
        self.bottomRightToolbar = NavigationToolbar2Tk( self.bottomRightCanvas, bottomRightFrame )
        self.bottomRightToolbar.update()
        self.bottomRightCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        controlsFrame = tk.Frame(self)
        controlsFrame.pack(side=tk.TOP,fill=tk.X,expand=tk.NO)
        self.sButtonsFrame = tk.Frame(controlsFrame, bd=1, relief=tk.SUNKEN)
        self.sButtonsFrame.pack(side=tk.LEFT,expand=tk.NO,fill=tk.NONE)
        self.resampleButton=tk.Button(controlsFrame,text='resample',command=self.onResample)
        self.resampleButton.pack(side=tk.LEFT,expand=tk.NO,fill=tk.NONE)

        self.sp=sp

        if buttonLabels is None:
            numPorts=self.sp.m_P
            buttonLabels=[['s'+str(toP+1)+str(fromP+1) for fromP in range(numPorts)] for toP in range(numPorts)]
            self.referenceImpedance=PartPropertyReferenceImpedance(self.sp.m_Z0)
            self.referenceImpedanceProperty=ViewerProperty(controlsFrame,self.referenceImpedance,self.onReferenceImpedanceEntered)
        else:
            # button labels are a proxy for transfer parameters (until I do something better)
            self.showPassivityViolations.set(False)
            self.ShowPassivityViolationsDoer.Activate(False)
            self.ShowCausalityViolationsDoer.Activate(False)
            self.ShowImpedanceDoer.Activate(False)
            #self.LogScaleDoer.Activate(False)
            self.EnforcePassivityDoer.Activate(False)
            self.EnforceCausalityDoer.Activate(False)
            self.WaveletDenoiseDoer.Activate(False)
            self.ReadSParametersFromFileDoer.Activate(False)

        self.buttonLabels=buttonLabels

        self.buttons=[]
        for toP in range(len(buttonLabels)):
            buttonrow=[]
            rowFrame=tk.Frame(self.sButtonsFrame)
            rowFrame.pack(side=tk.TOP,expand=tk.NO,fill=tk.NONE)
            for fromP in range(len(buttonLabels[0])):
                thisButton=tk.Button(rowFrame,text=buttonLabels[toP][fromP],width=len(buttonLabels[toP][fromP]),command=lambda x=toP+1,y=fromP+1: self.onSelectSParameter(x,y))
                thisButton.pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
                buttonrow.append(thisButton)
            self.buttons.append(buttonrow)

        self.fromPort = 1
        self.toPort = 1

        try:
            from matplotlib2tikz import save as tikz_save
        except:
            self.Matplotlib2tikzDoer.Activate(False)

        self.buttons[self.toPort-1][self.fromPort-1].config(relief=tk.SUNKEN)
        self.PlotSParameter()
        self.deiconify()
Example #16
0
class SParametersDialog(tk.Toplevel):
    def __init__(self, parent,sp,filename=None,title=None,buttonLabels=None):
        tk.Toplevel.__init__(self, parent)
        self.parent=parent
        self.withdraw()
        self.fileparts=FileParts(filename)
        if title is None:
            if self.fileparts.filename =='':
                self.title('S-parameters')
            else:
                self.title('S-parameters: '+self.fileparts.FileNameTitle())
        else:
            if filename is None:
                self.title(title)
            else:
                self.title(title+': '+self.fileparts.FileNameTitle())

        img = tk.PhotoImage(file=SignalIntegrity.App.IconsBaseDir+'AppIcon2.gif')
        self.tk.call('wm', 'iconphoto', self._w, img)
        self.protocol("WM_DELETE_WINDOW", self.onClosing)

        self.variableLineWidth = tk.BooleanVar()
        self.showPassivityViolations = tk.BooleanVar()
        self.showCausalityViolations = tk.BooleanVar()
        self.showImpedance = tk.BooleanVar()
        self.logScale =  tk.BooleanVar()

        # the Doers - the holder of the commands, menu elements, toolbar elements, and key bindings
        self.ReadSParametersFromFileDoer = Doer(self.onReadSParametersFromFile).AddKeyBindElement(self,'<Control-o>').AddHelpElement('Control-Help:Open-S-parameter-File')
        self.WriteSParametersToFileDoer = Doer(self.onWriteSParametersToFile).AddKeyBindElement(self,'<Control-s>').AddHelpElement('Control-Help:Save-S-parameter-File')
        self.Matplotlib2tikzDoer = Doer(self.onMatplotlib2TikZ)
        # ------
        self.CalculationPropertiesDoer = Doer(self.onCalculationProperties).AddHelpElement('Control-Help:Calculation-Properties')
        self.ResampleDoer = Doer(self.onResample).AddHelpElement('Control-Help:Resample')
        self.EnforcePassivityDoer = Doer(self.onEnforcePassivity).AddHelpElement('Control-Help:Enforce-Passivity')
        self.EnforceCausalityDoer = Doer(self.onEnforceCausality).AddHelpElement('Control-Help:Enforce-Causality')
        self.WaveletDenoiseDoer = Doer(self.onWaveletDenoise).AddHelpElement('Control-Help:Wavelet-Denoise')
        # ------
        self.HelpDoer = Doer(self.onHelp).AddHelpElement('Control-Help:Open-Help-File')
        self.ControlHelpDoer = Doer(self.onControlHelp).AddHelpElement('Control-Help:Control-Help')
        # ------
        self.VariableLineWidthDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Variable-Line-Width')
        self.ShowPassivityViolationsDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Show-Passivity-Violations')
        self.ShowCausalityViolationsDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Show-Causality-Violations')
        self.ShowImpedanceDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Show-Impedance')
        self.LogScaleDoer = Doer(self.PlotSParameter).AddHelpElement('Control-Help:Log-Scale')
        # ------
        self.EscapeDoer = Doer(self.onEscape).AddKeyBindElement(self,'<Escape>').DisableHelp()

        # The menu system
        TheMenu=tk.Menu(self)
        self.config(menu=TheMenu)
        # ------
        FileMenu=tk.Menu(self)
        TheMenu.add_cascade(label='File',menu=FileMenu,underline=0)
        self.WriteSParametersToFileDoer.AddMenuElement(FileMenu,label="Save",accelerator='Ctrl+S',underline=0)
        self.ReadSParametersFromFileDoer.AddMenuElement(FileMenu,label="Open File",accelerator='Ctrl+O',underline=0)
        FileMenu.add_separator()
        self.Matplotlib2tikzDoer.AddMenuElement(FileMenu,label='Output to LaTeX (TikZ)',underline=10)
        # ------
        CalcMenu=tk.Menu(self)
        TheMenu.add_cascade(label='Calculate',menu=CalcMenu,underline=0)
        self.CalculationPropertiesDoer.AddMenuElement(CalcMenu,label='Calculation Properties',underline=0)
        #CalcMenu.add_separator()
        self.ResampleDoer.AddMenuElement(CalcMenu,label='Resample',underline=0)
        #CalcMenu.add_separator()
        self.EnforcePassivityDoer.AddMenuElement(CalcMenu,label='Enforce Passivity',underline=8)
        self.EnforceCausalityDoer.AddMenuElement(CalcMenu,label='Enforce Causality',underline=9)
        self.WaveletDenoiseDoer.AddMenuElement(CalcMenu,label='Wavelet Denoise',underline=0)
        # ------
        ViewMenu=tk.Menu(self)
        TheMenu.add_cascade(label='View',menu=ViewMenu,underline=0)
        self.VariableLineWidthDoer.AddCheckButtonMenuElement(ViewMenu,label='Variable Line Width',underline=9,onvalue=True,offvalue=False,variable=self.variableLineWidth)
        self.ShowPassivityViolationsDoer.AddCheckButtonMenuElement(ViewMenu,label='Show Passivity Violations',underline=5,onvalue=True,offvalue=False,variable=self.showPassivityViolations)
        self.ShowCausalityViolationsDoer.AddCheckButtonMenuElement(ViewMenu,label='Show Causality Violations',underline=6,onvalue=True,offvalue=False,variable=self.showCausalityViolations)
        self.ShowImpedanceDoer.AddCheckButtonMenuElement(ViewMenu,label='Show Impedance',underline=5,onvalue=True,offvalue=False,variable=self.showImpedance)
        self.LogScaleDoer.AddCheckButtonMenuElement(ViewMenu,label='Log Scale',underline=4,onvalue=True,offvalue=False,variable=self.logScale)
        # ------
        HelpMenu=tk.Menu(self)
        TheMenu.add_cascade(label='Help',menu=HelpMenu,underline=0)
        self.HelpDoer.AddMenuElement(HelpMenu,label='Open Help File',underline=0)
        self.ControlHelpDoer.AddMenuElement(HelpMenu,label='Control Help',underline=0)

        # The Toolbar
        ToolBarFrame = tk.Frame(self)
        ToolBarFrame.pack(side=tk.TOP,fill=tk.X,expand=tk.NO)
        self.ReadSParametersFromFileDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'document-open-2.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
        self.WriteSParametersToFileDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'document-save-2.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
        tk.Frame(self,bd=2,relief=tk.SUNKEN).pack(side=tk.LEFT,fill=tk.X,padx=5,pady=5)
        self.CalculationPropertiesDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'tooloptions.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
        tk.Frame(ToolBarFrame,height=2,bd=2,relief=tk.RAISED).pack(side=tk.LEFT,fill=tk.X,padx=5,pady=5)
        self.HelpDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'help-contents-5.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
        self.ControlHelpDoer.AddToolBarElement(ToolBarFrame,iconfile=SignalIntegrity.App.IconsDir+'help-3.gif').Pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)

        topFrame=tk.Frame(self)
        topFrame.pack(side=tk.TOP,fill=tk.BOTH,expand=tk.YES)
        bottomFrame=tk.Frame(self)
        bottomFrame.pack(side=tk.TOP,fill=tk.BOTH,expand=tk.YES)
        topLeftFrame=tk.Frame(topFrame)
        topLeftFrame.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)
        topRightFrame=tk.Frame(topFrame)
        topRightFrame.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)
        bottomLeftFrame=tk.Frame(bottomFrame)
        bottomLeftFrame.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)
        bottomRightFrame=tk.Frame(bottomFrame)
        bottomRightFrame.pack(side=tk.LEFT,fill=tk.BOTH,expand=tk.YES)

        self.topLeftFigure=Figure(figsize=(5,2), dpi=100)
        self.topLeftPlot=self.topLeftFigure.add_subplot(111)
        self.topLeftCanvas=FigureCanvasTkAgg(self.topLeftFigure, master=topLeftFrame)
        self.topLeftCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.X, expand=1)
        self.topLeftToolbar = NavigationToolbar2Tk( self.topLeftCanvas, topLeftFrame )
        self.topLeftToolbar.update()
        self.topLeftCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        self.topRightFigure=Figure(figsize=(5,2), dpi=100)
        self.topRightPlot=self.topRightFigure.add_subplot(111)
        self.topRightCanvas=FigureCanvasTkAgg(self.topRightFigure, master=topRightFrame)
        self.topRightCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.X, expand=1)
        self.topRightToolbar = NavigationToolbar2Tk( self.topRightCanvas, topRightFrame )
        self.topRightToolbar.update()
        self.topRightCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.topRightCanvasControlsFrame=tk.Frame(topRightFrame)
        self.topRightCanvasControlsFrame.pack(side=tk.TOP, fill=tk.X, expand=tk.NO)
        tk.Button(self.topRightCanvasControlsFrame,text='unwrap',command=self.onUnwrap).pack(side=tk.LEFT,expand=tk.NO,fill=tk.NONE)
        self.delay=PartPropertyDelay(0.)
        self.delayViewerProperty=ViewerProperty(self.topRightCanvasControlsFrame,self.delay,self.onDelayEntered)

        self.bottomLeftFigure=Figure(figsize=(5,2), dpi=100)
        self.bottomLeftPlot=self.bottomLeftFigure.add_subplot(111)
        self.bottomLeftCanvas=FigureCanvasTkAgg(self.bottomLeftFigure, master=bottomLeftFrame)
        self.bottomLeftCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.X, expand=1)
        self.bottomLeftToolbar = NavigationToolbar2Tk( self.bottomLeftCanvas, bottomLeftFrame )
        self.bottomLeftToolbar.update()
        self.bottomLeftCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        self.bottomRightFigure=Figure(figsize=(5,2), dpi=100)
        self.bottomRightPlot=self.bottomRightFigure.add_subplot(111)
        self.bottomRightCanvas=FigureCanvasTkAgg(self.bottomRightFigure, master=bottomRightFrame)
        self.bottomRightCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.X, expand=1)
        self.bottomRightToolbar = NavigationToolbar2Tk( self.bottomRightCanvas, bottomRightFrame )
        self.bottomRightToolbar.update()
        self.bottomRightCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        controlsFrame = tk.Frame(self)
        controlsFrame.pack(side=tk.TOP,fill=tk.X,expand=tk.NO)
        self.sButtonsFrame = tk.Frame(controlsFrame, bd=1, relief=tk.SUNKEN)
        self.sButtonsFrame.pack(side=tk.LEFT,expand=tk.NO,fill=tk.NONE)
        self.resampleButton=tk.Button(controlsFrame,text='resample',command=self.onResample)
        self.resampleButton.pack(side=tk.LEFT,expand=tk.NO,fill=tk.NONE)

        self.sp=sp

        if buttonLabels is None:
            numPorts=self.sp.m_P
            buttonLabels=[['s'+str(toP+1)+str(fromP+1) for fromP in range(numPorts)] for toP in range(numPorts)]
            self.referenceImpedance=PartPropertyReferenceImpedance(self.sp.m_Z0)
            self.referenceImpedanceProperty=ViewerProperty(controlsFrame,self.referenceImpedance,self.onReferenceImpedanceEntered)
        else:
            # button labels are a proxy for transfer parameters (until I do something better)
            self.showPassivityViolations.set(False)
            self.ShowPassivityViolationsDoer.Activate(False)
            self.ShowCausalityViolationsDoer.Activate(False)
            self.ShowImpedanceDoer.Activate(False)
            #self.LogScaleDoer.Activate(False)
            self.EnforcePassivityDoer.Activate(False)
            self.EnforceCausalityDoer.Activate(False)
            self.WaveletDenoiseDoer.Activate(False)
            self.ReadSParametersFromFileDoer.Activate(False)

        self.buttonLabels=buttonLabels

        self.buttons=[]
        for toP in range(len(buttonLabels)):
            buttonrow=[]
            rowFrame=tk.Frame(self.sButtonsFrame)
            rowFrame.pack(side=tk.TOP,expand=tk.NO,fill=tk.NONE)
            for fromP in range(len(buttonLabels[0])):
                thisButton=tk.Button(rowFrame,text=buttonLabels[toP][fromP],width=len(buttonLabels[toP][fromP]),command=lambda x=toP+1,y=fromP+1: self.onSelectSParameter(x,y))
                thisButton.pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
                buttonrow.append(thisButton)
            self.buttons.append(buttonrow)

        self.fromPort = 1
        self.toPort = 1

        try:
            from matplotlib2tikz import save as tikz_save
        except:
            self.Matplotlib2tikzDoer.Activate(False)

        self.buttons[self.toPort-1][self.fromPort-1].config(relief=tk.SUNKEN)
        self.PlotSParameter()
        self.deiconify()
#         self.geometry("%+d%+d" % (self.parent.root.winfo_x()+self.parent.root.winfo_width()/2-self.winfo_width()/2,
#             self.parent.root.winfo_y()+self.parent.root.winfo_height()/2-self.winfo_height()/2))

    def onClosing(self):
        self.withdraw()
        self.destroy()

    def destroy(self):
        tk.Toplevel.withdraw(self)
        tk.Toplevel.destroy(self)

    def PlotSParameter(self):
        import SignalIntegrity.Lib as si
        self.topLeftPlot.cla()
        self.topRightPlot.cla()
        self.bottomLeftPlot.cla()
        self.bottomRightPlot.cla()
        
        if not SignalIntegrity.App.Preferences['Appearance.PlotCursorValues']:
            self.topLeftPlot.format_coord = lambda x, y: ''
            self.topRightPlot.format_coord = lambda x, y: ''
            self.bottomLeftPlot.format_coord = lambda x, y: ''
            self.bottomRightPlot.format_coord = lambda x, y: ''

        fr=self.sp.FrequencyResponse(self.toPort,self.fromPort)
        ir=fr.ImpulseResponse()

        y=fr.Response('dB')

        self.freqLabel=ToSI(fr.Frequencies()[-1],'Hz')[-3:]
        freqLabelDivisor=FromSI('1. '+self.freqLabel,'Hz')

        x=fr.Frequencies(freqLabelDivisor)

        if self.showPassivityViolations.get():
            self.passivityViolations=[]
            s=self.sp._LargestSingularValues()
            for n in range(len(s)):
                if s[n]-1 > 1e-15:
                    dotsize=max(min(20.,math.log10(s[0])/math.log10(1.01)*20.),1e-15)
                    self.passivityViolations.append([x[n],y[n],dotsize])

        lw=[min(1.,math.sqrt(w))*1.5 for w in fr.Response('mag')]

        fastway=True

# this works - properly displays on log plot, only it is just too slow!
#         if self.logScale.get():
#             fastway=False

        if self.variableLineWidth.get():
            if fastway:
                segments = [[[x[i],y[i]],[x[i+1],y[i+1]]] for i in range(len(x)-1)]
                slw=lw[:-1]
                lc = LineCollection(segments, linewidths=slw,color='blue')
                self.topLeftPlot.add_collection(lc)
            else:
                for i in range(len(x)-1):
                    if self.logScale.get():
                        self.topLeftPlot.semilogx(x[i:i+2],y[i:i+2],linewidth=lw[i],color='blue')
                    else:
                        self.topLeftPlot.plot(x[i:i+2],y[i:i+2],linewidth=lw[i],color='blue')
        else:
            if self.logScale.get():
                self.topLeftPlot.semilogx(x,y)
            else:
                self.topLeftPlot.plot(x,y)

        if self.showPassivityViolations.get():
            self.topLeftPlot.scatter(
                [c[0] for c in self.passivityViolations],
                [c[1] for c in self.passivityViolations],
                s=[c[2] for c in self.passivityViolations],
                color='red')

        self.topLeftPlot.set_xlim(xmin=min(x))
        self.topLeftPlot.set_xlim(xmax=max(x))
        self.topLeftPlot.set_ylim(ymin=max(min(y)-1.,-60.0))
        self.topLeftPlot.set_ylim(ymax=max(y)+1.)
        self.topLeftPlot.set_ylabel('magnitude (dB)',fontsize=10)
        self.topLeftPlot.set_xlabel('frequency ('+self.freqLabel+')',fontsize=10)

        y=fr.Response('deg')
        x=fr.Frequencies(freqLabelDivisor)

        if self.variableLineWidth.get():
            if fastway:
                segments = [[[x[i],y[i]],[x[i+1],y[i+1]]] for i in range(len(x)-1)]
                slw=lw[:-1]
                lc = LineCollection(segments, linewidths=slw,color='blue')
                self.topRightPlot.add_collection(lc)
            else:
                for i in range(len(x)-1):
                    if self.logScale.get():
                        self.topRightPlot.semilogx(x[i:i+2],y[i:i+2],linewidth=lw[i],color='blue')
                    else:
                        self.topRightPlot.plot(x[i:i+2],y[i:i+2],linewidth=lw[i],color='blue')
        else:
            if self.logScale.get():
                self.topRightPlot.semilogx(x,y)
            else:
                self.topRightPlot.plot(x,y)

        self.topRightPlot.set_xlim(xmin=min(x))
        self.topRightPlot.set_xlim(xmax=max(x))
        self.topRightPlot.set_ylim(ymin=min(y)-1)
        self.topRightPlot.set_ylim(ymax=max(y)+1)
        self.topRightPlot.set_ylabel('phase (degrees)',fontsize=10)
        self.topRightPlot.set_xlabel('frequency ('+self.freqLabel+')',fontsize=10)

        if ir is not None:
            if self.buttonLabels[self.toPort-1][self.fromPort-1][:2]=='i/' or self.buttonLabels[self.toPort-1][self.fromPort-1][:3]=='di/':
                print('Integrate')
                ir=si.td.wf.ImpulseResponse(ir.Integral(addPoint=False))
            if self.buttonLabels[self.toPort-1][self.fromPort-1][:3]=='di/':
                print('Integrate')
                ir=si.td.wf.ImpulseResponse(ir.Integral(addPoint=False)*ir.td.Fs)

            y=ir.Values()

            timeLabel=ToSI(ir.Times()[-1],'s')[-2:]
            timeLabelDivisor=FromSI('1. '+timeLabel,'s')

            x=ir.Times(timeLabelDivisor)

            self.bottomLeftPlot.plot(x,y)

            if self.showCausalityViolations.get():
                self.causalityViolations=[]
                Ts=1./ir.td.Fs/1e-9
                for k in range(len(x)):
                    if x[k]<=-Ts and abs(y[k])>0:
                        dotsize=max(min(20.,abs(y[k])/0.1*20.),1e-15)
                        self.causalityViolations.append([x[k],y[k],dotsize])
                self.bottomLeftPlot.scatter(
                    [c[0] for c in self.causalityViolations],
                    [c[1] for c in self.causalityViolations],
                    s=[c[2] for c in self.causalityViolations],
                    color='red')

            self.bottomLeftPlot.set_ylim(ymin=min(min(y)*1.05,-0.1))
            self.bottomLeftPlot.set_ylim(ymax=max(max(y)*1.05,0.1))
            self.bottomLeftPlot.set_xlim(xmin=min(x))
            self.bottomLeftPlot.set_xlim(xmax=max(x))
            self.bottomLeftPlot.set_ylabel('amplitude',fontsize=10)
            self.bottomLeftPlot.set_xlabel('time ('+timeLabel+')',fontsize=10)

            firFilter=ir.FirFilter()
            stepWaveformTimeDescriptor=ir.td/firFilter.FilterDescriptor()
            stepWaveform=si.td.wf.StepWaveform(stepWaveformTimeDescriptor)
            stepResponse=stepWaveform*firFilter
            y=stepResponse.Values()
            x=stepResponse.Times(timeLabelDivisor)

            if self.showImpedance.get() and (self.fromPort == self.toPort):
                Z0=self.referenceImpedance.GetValue()
                y=[3000. if (1-yv)<=.000001 else min(Z0*(1+yv)/(1-yv),3000) for yv in y]
                x=[xv/2 for xv in x]
                self.bottomRightPlot.set_ylabel('impedance (Ohms)',fontsize=10)
                self.bottomRightPlot.set_xlabel('length ('+timeLabel+')',fontsize=10)
                self.bottomRightPlot.set_ylim(ymin=min(min(y)*1.05,Z0-1))
            else:
                self.bottomRightPlot.set_ylabel('amplitude',fontsize=10)
                self.bottomRightPlot.set_xlabel('time ('+timeLabel+')',fontsize=10)
                self.bottomRightPlot.set_ylim(ymin=min(min(y)*1.05,-0.1))

            self.bottomRightPlot.plot(x,y)

            self.bottomRightPlot.set_ylim(ymax=max(max(y)*1.05,0.1))
            self.bottomRightPlot.set_xlim(xmin=min(x))
            self.bottomRightPlot.set_xlim(xmax=max(x))

        self.topLeftCanvas.draw()
        self.topRightCanvas.draw()
        self.bottomLeftCanvas.draw()
        self.bottomRightCanvas.draw()

    def onSelectSParameter(self,toP,fromP):
        self.buttons[self.toPort-1][self.fromPort-1].config(relief=tk.RAISED)
        self.toPort = toP
        self.fromPort = fromP
        self.buttons[self.toPort-1][self.fromPort-1].config(relief=tk.SUNKEN)
        self.delay.SetValueFromString(str(0))
        self.delayViewerProperty.onUntouched(None)
        self.PlotSParameter()

    def onAutoscale(self):
        self.plt.autoscale(True)
        self.f.canvas.draw()

    def onUnwrap(self):
        fr=self.sp.FrequencyResponse(self.toPort,self.fromPort)
        ir=fr.ImpulseResponse()
        if ir is not None:
            idx = ir.Values('abs').index(max(ir.Values('abs')))
            TD = ir.Times()[idx] # the time of the main peak
        else:
            TD=0.
        self.delay.SetValueFromString(str(TD))
        self.delayViewerProperty.onUntouched(None)

    def onDelayEntered(self):
        self.topRightPlot.cla()
        fr=self.sp.FrequencyResponse(self.toPort,self.fromPort)
        TD = self.delay.GetValue()
        fr=fr._DelayBy(-TD)
        lw=[min(1.,math.sqrt(w))*1.5 for w in fr.Response('mag')]
        y=fr.Response('deg')
        x=fr.Frequencies('GHz')
        fastway=True
        if self.variableLineWidth.get():
            if fastway:
                segments = [[[x[i],y[i]],[x[i+1],y[i+1]]] for i in range(len(x)-1)]
                slw=lw[:-1]
                lc = LineCollection(segments, linewidths=slw,color='blue')
                self.topRightPlot.add_collection(lc)
            else:
                for i in range(len(x)-1):
                    if self.logScale.get():
                        self.topRightPlot.semilogx(x[i:i+2],y[i:i+2],linewidth=lw[i],color='blue')
                    else:
                        self.topRightPlot.plot(x[i:i+2],y[i:i+2],linewidth=lw[i],color='blue')
        else:
            if self.logScale.get():
                self.topRightPlot.semilogx(x,y)
            else:
                self.topRightPlot.plot(x,y)
        self.topRightPlot.set_xlim(xmin=min(x))
        self.topRightPlot.set_xlim(xmax=max(x))
        self.topRightPlot.set_ylim(ymin=min(y)-1)
        self.topRightPlot.set_ylim(ymax=max(y)+1)
        self.topRightPlot.set_ylabel('phase (degrees)',fontsize=10)
        self.topRightPlot.set_xlabel('frequency ('+self.freqLabel+')',fontsize=10)
        self.topRightCanvas.draw()

    def onReferenceImpedanceEntered(self):
        self.sp.SetReferenceImpedance(self.referenceImpedance.GetValue())
        self.PlotSParameter()

    def onReadSParametersFromFile(self):
        import SignalIntegrity.Lib as si
        filename=AskOpenFileName(filetypes=[('s-parameter files', ('*.s*p'))],
                                 initialdir=self.fileparts.AbsoluteFilePath(),
                                 parent=self)
        if filename is None:
            return
        self.fileparts=FileParts(filename)
        if self.fileparts.fileext=='':
            return

        self.title('S-parameters: '+self.fileparts.FileNameTitle())

        self.sp=si.sp.SParameterFile(filename)
        self.referenceImpedance.SetValueFromString(str(self.sp.m_Z0))
        self.referenceImpedanceProperty.propertyString.set(self.referenceImpedance.PropertyString(stype='entry'))
        for widget in self.sButtonsFrame.winfo_children():
            widget.destroy()
        numPorts=self.sp.m_P
        self.buttonLabels=[['s'+str(toP+1)+str(fromP+1) for fromP in range(numPorts)] for toP in range(numPorts)]
        self.buttons=[]
        for toP in range(numPorts):
            buttonrow=[]
            rowFrame=tk.Frame(self.sButtonsFrame)
            rowFrame.pack(side=tk.TOP,expand=tk.NO,fill=tk.NONE)
            for fromP in range(numPorts):
                thisButton=tk.Button(rowFrame,text=self.buttonLabels[toP][fromP],command=lambda x=toP+1,y=fromP+1: self.onSelectSParameter(x,y))
                thisButton.pack(side=tk.LEFT,fill=tk.NONE,expand=tk.NO)
                buttonrow.append(thisButton)
            self.buttons.append(buttonrow)
        self.fromPort = 1
        self.toPort = 1
        self.buttons[self.toPort-1][self.fromPort-1].config(relief=tk.SUNKEN)
        self.PlotSParameter()

    def onWriteSParametersToFile(self):
        ports=self.sp.m_P
        extension='.s'+str(ports)+'p'
        filename=AskSaveAsFilename(filetypes=[('s-parameters', extension)],
                    defaultextension=extension,
                    initialdir=self.fileparts.AbsoluteFilePath(),
                    initialfile=self.fileparts.FileNameWithExtension(extension),
                    parent=self)
        if filename is None:
            return
        self.fileparts=FileParts(filename)
        self.sp.WriteToFile(filename,'R '+str(self.sp.m_Z0))

    def onResample(self):
        import SignalIntegrity.Lib as si
        self.sp=self.sp.Resample(si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.Project['CalculationProperties.FrequencyPoints']))
        self.PlotSParameter()

    def onCalculationProperties(self):
        self.parent.onCalculationProperties()

    def onMatplotlib2TikZ(self):
        filename=AskSaveAsFilename(parent=self,filetypes=[('tex', '.tex')],
                                   defaultextension='.tex',
                                   initialdir=self.fileparts.AbsoluteFilePath(),
                                   initialfile=self.fileparts.filename+'Magnitude.tex')
        if filename is None:
            return

        try:
            PlotTikZ(filename,self.topLeftFigure)
        except:
            messagebox.showerror('Export LaTeX','LaTeX could not be generated or written ')                
        fp=FileParts(filename.replace('Magnitude.tex', ''))
        filename=fp.filename

        filename=AskSaveAsFilename(parent=self,filetypes=[('tex', '.tex')],
                                   defaultextension='.tex',
                                   initialdir=self.fileparts.AbsoluteFilePath(),
                                   initialfile=filename+'Phase.tex')
        if filename is None:
            return

        try:
            PlotTikZ(filename,self.topRightFigure)
        except:
            messagebox.showerror('Export LaTeX','LaTeX could not be generated or written ')                
        fp=FileParts(filename.replace('Phase.tex', ''))
        filename=fp.filename

        filename=AskSaveAsFilename(parent=self,filetypes=[('tex', '.tex')],
                                   defaultextension='.tex',
                                   initialdir=self.fileparts.AbsoluteFilePath(),
                                   initialfile=filename+'ImpulseResponse.tex')
        if filename is None:
            return

        try:
            PlotTikZ(filename,self.bottomLeftFigure)
        except:
            messagebox.showerror('Export LaTeX','LaTeX could not be generated or written ')                
        fp=FileParts(filename.replace('ImpulseResponse.tex', ''))
        filename=fp.filename

        filename=AskSaveAsFilename(parent=self,filetypes=[('tex', '.tex')],
                                   defaultextension='.tex',
                                   initialdir=self.fileparts.AbsoluteFilePath(),
                                   initialfile=filename+'StepResponse.tex')
        if filename is None:
            return

        try:
            PlotTikZ(filename,self.bottomRightFigure)
        except:
            messagebox.showerror('Export LaTeX','LaTeX could not be generated or written ')

    def onHelp(self):
        if Doer.helpKeys is None:
            messagebox.showerror('Help System','Cannot find or open this help element')            
            return
        Doer.helpKeys.Open('sec:S-parameter-Viewer')

    def onControlHelp(self):
        Doer.inHelp=True
        self.config(cursor='question_arrow')

    def onEscape(self):
        Doer.inHelp=False
        self.config(cursor='left_ptr')

    def onEnforcePassivity(self):
        self.sp.EnforcePassivity()
        self.PlotSParameter()

    def onEnforceCausality(self):
        self.sp.EnforceCausality()
        self.PlotSParameter()

    def onWaveletDenoise(self):
        self.sp.WaveletDenoise()
        self.PlotSParameter()
 def SaveProjectToFile(self, filename):
     self.fileparts = FileParts(filename)
     os.chdir(self.fileparts.AbsoluteFilePath())
     self.fileparts = FileParts(filename)
     SignalIntegrity.App.Project.Write(self, filename)
Example #18
0
class SignalIntegrityAppHeadless(object):
    projectStack = ProjectStack()

    def __init__(self):
        # make absolutely sure the directory of this file is the first in the
        # python path
        thisFileDir = os.path.dirname(os.path.realpath(__file__))
        sys.path = [thisFileDir] + sys.path
        SignalIntegrity.App.Preferences = Preferences()
        SignalIntegrity.App.InstallDir = os.path.dirname(
            os.path.abspath(__file__))
        self.Drawing = DrawingHeadless(self)

    def NullCommand(self):
        pass

    def OpenProjectFile(self, filename):
        if filename is None:
            filename = ''
        if isinstance(filename, tuple):
            filename = ''
        filename = str(filename)
        if filename == '':
            return False
        try:
            self.fileparts = FileParts(filename)
            os.chdir(self.fileparts.AbsoluteFilePath())
            self.fileparts = FileParts(filename)
            SignalIntegrity.App.Project = ProjectFile().Read(
                self.fileparts.FullFilePathExtension('.si'))
            self.Drawing.InitFromProject()
        except:
            return False
        self.Drawing.schematic.Consolidate()
        for device in self.Drawing.schematic.deviceList:
            device.selected = False
        for wireProject in SignalIntegrity.App.Project[
                'Drawing.Schematic.Wires']:
            for vertexProject in wireProject['Vertices']:
                vertexProject['Selected'] = False
        return True

    def SaveProjectToFile(self, filename):
        self.fileparts = FileParts(filename)
        os.chdir(self.fileparts.AbsoluteFilePath())
        self.fileparts = FileParts(filename)
        SignalIntegrity.App.Project.Write(self, filename)

    def SaveProject(self):
        if self.fileparts.filename == '':
            return
        filename = self.fileparts.AbsoluteFilePath(
        ) + '/' + self.fileparts.FileNameWithExtension(ext='.si')
        self.SaveProjectToFile(filename)

    def NetListText(self):
        return self.Drawing.schematic.NetList().Text(
        ) + SignalIntegrity.App.Project['PostProcessing'].NetListLines()

    def config(self, cursor=None):
        pass

    def CalculateSParameters(self):
        import SignalIntegrity.Lib as si
        if not hasattr(self.Drawing, 'canCalculate'):
            self.Drawing.DrawSchematic()
        if self.Drawing.canCalculateSParametersFromNetworkAnalyzerModel:
            try:
                sp = self.SimulateNetworkAnalyzerModel(SParameters=True)
            except si.SignalIntegrityException as e:
                return None
            return (sp,
                    self.fileparts.FullFilePathExtension('s' + str(sp.m_P) +
                                                         'p'))
        elif not self.Drawing.canCalculateSParameters:
            return None
        netListText = self.NetListText()
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle()
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        spnp = si.p.SystemSParametersNumericParser(
            si.fd.EvenlySpacedFrequencyList(
                SignalIntegrity.App.
                Project['CalculationProperties.EndFrequency'], SignalIntegrity.
                App.Project['CalculationProperties.FrequencyPoints']),
            cacheFileName=cacheFileName)
        spnp.AddLines(netListText)
        try:
            sp = spnp.SParameters()
        except si.SignalIntegrityException as e:
            return None
        return (sp,
                self.fileparts.FullFilePathExtension('s' + str(sp.m_P) + 'p'))

    def Simulate(self):
        if not hasattr(self.Drawing, 'canCalculate'):
            self.Drawing.DrawSchematic()
        if self.Drawing.canSimulateNetworkAnalyzerModel:
            return self.SimulateNetworkAnalyzerModel(SParameters=False)
        elif not self.Drawing.canSimulate:
            return None
        netList = self.Drawing.schematic.NetList()
        netListText = self.NetListText()
        import SignalIntegrity.Lib as si
        fd = si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints'])
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle()
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        snp = si.p.SimulatorNumericParser(fd, cacheFileName=cacheFileName)
        snp.AddLines(netListText)
        try:
            transferMatrices = snp.TransferMatrices()
        except si.SignalIntegrityException as e:
            return None

        outputWaveformLabels = netList.OutputNames()

        try:
            inputWaveformList = self.Drawing.schematic.InputWaveforms()
            sourceNames = netList.SourceNames()
        except si.SignalIntegrityException as e:
            return None

        transferMatricesProcessor = si.td.f.TransferMatricesProcessor(
            transferMatrices)
        si.td.wf.Waveform.adaptionStrategy = 'SinX' if SignalIntegrity.App.Preferences[
            'Calculation.UseSinX'] else 'Linear'

        try:
            outputWaveformList = transferMatricesProcessor.ProcessWaveforms(
                inputWaveformList)
        except si.SignalIntegrityException as e:
            return None

        for outputWaveformIndex in range(len(outputWaveformList)):
            outputWaveform = outputWaveformList[outputWaveformIndex]
            outputWaveformLabel = outputWaveformLabels[outputWaveformIndex]
            for device in self.Drawing.schematic.deviceList:
                if device['partname'].GetValue() in [
                        'Output', 'DifferentialVoltageOutput', 'CurrentOutput'
                ]:
                    if device['ref'].GetValue() == outputWaveformLabel:
                        # probes may have different kinds of gain specified
                        gainProperty = device['gain']
                        gain = gainProperty.GetValue()
                        offset = device['offset'].GetValue()
                        delay = device['td'].GetValue()
                        if gain != 1.0 or offset != 0.0 or delay != 0.0:
                            outputWaveform = outputWaveform.DelayBy(
                                delay) * gain + offset
                        outputWaveformList[
                            outputWaveformIndex] = outputWaveform
                        break
        userSampleRate = SignalIntegrity.App.Project[
            'CalculationProperties.UserSampleRate']
        outputWaveformList = [
            wf.Adapt(
                si.td.wf.TimeDescriptor(
                    wf.td.H, int(wf.td.K * userSampleRate / wf.td.Fs),
                    userSampleRate)) for wf in outputWaveformList
        ]
        return (sourceNames, outputWaveformLabels, transferMatrices,
                outputWaveformList)

    def VirtualProbe(self):
        netList = self.Drawing.schematic.NetList()
        netListText = self.NetListText()
        import SignalIntegrity.Lib as si
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle()
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        snp = si.p.VirtualProbeNumericParser(si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints']),
                                             cacheFileName=cacheFileName)
        snp.AddLines(netListText)
        try:
            transferMatrices = snp.TransferMatrices()
        except si.SignalIntegrityException as e:
            return None

        transferMatricesProcessor = si.td.f.TransferMatricesProcessor(
            transferMatrices)
        si.td.wf.Waveform.adaptionStrategy = 'SinX' if SignalIntegrity.App.Preferences[
            'Calculation.UseSinX'] else 'Linear'

        try:
            inputWaveformList = self.Drawing.schematic.InputWaveforms()
            sourceNames = netList.MeasureNames()
        except si.SignalIntegrityException as e:
            return None

        try:
            outputWaveformList = transferMatricesProcessor.ProcessWaveforms(
                inputWaveformList)
        except si.SignalIntegrityException as e:
            return None

        outputWaveformLabels = netList.OutputNames()

        for outputWaveformIndex in range(len(outputWaveformList)):
            outputWaveform = outputWaveformList[outputWaveformIndex]
            outputWaveformLabel = outputWaveformLabels[outputWaveformIndex]
            for device in self.Drawing.schematic.deviceList:
                if device['partname'].GetValue() in [
                        'Output', 'DifferentialVoltageOutput', 'CurrentOutput'
                ]:
                    if device['ref'].GetValue() == outputWaveformLabel:
                        # probes may have different kinds of gain specified
                        gainProperty = device['gain']
                        gain = gainProperty.GetValue()
                        offset = device['offset'].GetValue()
                        delay = device['td'].GetValue()
                        if gain != 1.0 or offset != 0.0 or delay != 0.0:
                            outputWaveform = outputWaveform.DelayBy(
                                delay) * gain + offset
                        outputWaveformList[
                            outputWaveformIndex] = outputWaveform
                        break
        userSampleRate = SignalIntegrity.App.Project[
            'CalculationProperties.UserSampleRate']
        outputWaveformList = [
            wf.Adapt(
                si.td.wf.TimeDescriptor(
                    wf.td.H, int(wf.td.K * userSampleRate / wf.td.Fs),
                    userSampleRate)) for wf in outputWaveformList
        ]
        return (sourceNames, outputWaveformLabels, transferMatrices,
                outputWaveformList)

    def Deembed(self):
        netListText = self.NetListText()
        import SignalIntegrity.Lib as si
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle()
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        dnp = si.p.DeembedderNumericParser(si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints']),
                                           cacheFileName=cacheFileName)
        dnp.AddLines(netListText)

        try:
            sp = dnp.Deembed()
        except si.SignalIntegrityException as e:
            return None

        unknownNames = dnp.m_sd.UnknownNames()
        if len(unknownNames) == 1:
            sp = [sp]

        return (unknownNames, sp)

        filename = []
        for u in range(len(unknownNames)):
            extension = '.s' + str(sp[u].m_P) + 'p'
            filename = unknownNames[u] + extension
            if self.fileparts.filename != '':
                filename.append(self.fileparts.filename + '_' + filename)
        return (unknownNames, sp, filename)

    def CalculateErrorTerms(self):
        if not hasattr(self.Drawing, 'canCalculate'):
            self.Drawing.DrawSchematic()
        if not self.Drawing.canCalculateErrorTerms:
            return None
        netList = self.Drawing.schematic.NetList()
        netListText = self.NetListText()
        import SignalIntegrity.Lib as si
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle()
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        etnp = si.p.CalibrationNumericParser(si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints']),
                                             cacheFileName=cacheFileName)
        etnp.AddLines(netListText)
        try:
            cal = etnp.CalculateCalibration()
        except si.SignalIntegrityException as e:
            return None
        return (cal, self.fileparts.FullFilePathExtension('cal'))

    def Device(self, ref):
        """
        accesses a device by it's reference string
        @param ref string reference designator
        @return device if found otherwise None

        Some examples of how to use this (proj is a project name)
        gain=proj.Device('U1')['gain']['Value']
        proj.Device('U1')['gain']['Value']=gain
        """
        devices = self.Drawing.schematic.deviceList
        for device in devices:
            if device['ref']['Value'] == ref:
                return device
        return None

    def SimulateNetworkAnalyzerModel(self, SParameters=False):
        netList = self.Drawing.schematic.NetList().Text()
        import SignalIntegrity.Lib as si
        fd = si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints'])
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle() + '_DUTSParameters'
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        spnp = si.p.DUTSParametersNumericParser(fd,
                                                cacheFileName=cacheFileName)
        spnp.AddLines(netList)
        try:
            (DUTSp, NetworkAnalyzerProjectFile) = spnp.SParameters()
        except si.SignalIntegrityException as e:
            return None
        netListText = None
        if NetworkAnalyzerProjectFile != None:
            level = SignalIntegrityAppHeadless.projectStack.Push()
            try:
                app = SignalIntegrityAppHeadless()
                if app.OpenProjectFile(
                        os.path.realpath(NetworkAnalyzerProjectFile)):
                    app.Drawing.DrawSchematic()
                    netList = app.Drawing.schematic.NetList()
                    netListText = netList.Text()
                else:
                    pass
            except:
                pass
            finally:
                SignalIntegrityAppHeadless.projectStack.Pull(level)
        else:
            netList = self.Drawing.schematic.NetList()
            netListText = self.NetListText()

        if netListText == None:
            return None
        cacheFileName = None
        if SignalIntegrity.App.Preferences['Cache.CacheResults']:
            cacheFileName = self.fileparts.FileNameTitle(
            ) + '_TransferMatrices'
        si.sd.Numeric.trySVD = SignalIntegrity.App.Preferences[
            'Calculation.TrySVD']
        snp = si.p.NetworkAnalyzerSimulationNumericParser(
            fd,
            DUTSp,
            spnp.NetworkAnalyzerPortConnectionList,
            cacheFileName=cacheFileName)
        snp.AddLines(netListText)
        level = SignalIntegrityAppHeadless.projectStack.Push()
        try:
            os.chdir(
                FileParts(os.path.abspath(
                    NetworkAnalyzerProjectFile)).AbsoluteFilePath())
            transferMatrices = snp.TransferMatrices()
        except si.SignalIntegrityException as e:
            return None
        finally:
            SignalIntegrityAppHeadless.projectStack.Pull(level)

        sourceNames = snp.m_sd.SourceVector()

        gdoDict = {}

        if NetworkAnalyzerProjectFile != None:
            level = SignalIntegrityAppHeadless.projectStack.Push()
            try:
                app = SignalIntegrityAppHeadless()
                if app.OpenProjectFile(
                        os.path.realpath(NetworkAnalyzerProjectFile)):
                    app.Drawing.DrawSchematic()
                    # get output gain, offset, delay
                    for name in [rdn[2] for rdn in snp.m_sd.pOutputList]:
                        gdoDict[name] = {
                            'gain': float(app.Device(name)['gain']['Value']),
                            'offset':
                            float(app.Device(name)['offset']['Value']),
                            'delay': float(app.Device(name)['td']['Value'])
                        }
                    stateList = [
                        app.Device(sourceNames[port])['state']['Value']
                        for port in range(snp.simulationNumPorts)
                    ]
                    self.wflist = []
                    for driven in range(snp.simulationNumPorts):
                        thiswflist = []
                        for port in range(snp.simulationNumPorts):
                            app.Device(sourceNames[port])['state'][
                                'Value'] = 'on' if port == driven else 'off'
                        for wfIndex in range(len(sourceNames)):
                            thiswflist.append(
                                app.Device(sourceNames[wfIndex]).Waveform())
                        self.wflist.append(thiswflist)
                    for port in range(snp.simulationNumPorts):
                        app.Device(sourceNames[port]
                                   )['state']['Value'] = stateList[port]
                else:
                    pass
            except:
                pass
            finally:
                SignalIntegrityAppHeadless.projectStack.Pull(level)
        else:
            stateList = [
                app.Device(sourceNames[port])['state']['Value']
                for port in range(snp.simulationNumPorts)
            ]
            self.wflist = []
            for name in [rdn[2] for rdn in snp.m_sd.pOutputList]:
                gdoDict[name] = {
                    'gain': float(app.Device()[name]['gain']['Value']),
                    'offset': float(app.Device()[name]['offset']['Value']),
                    'delay': float(app.Device()[name]['td']['Value'])
                }
            for driven in range(snp.simulationNumPorts):
                thiswflist = []
                for port in range(snp.simulationNumPorts):
                    app.Device(
                        sourceNames[port]
                    )['state']['Value'] = 'on' if port == driven else 'off'
                for wfIndex in range(len(sourceNames)):
                    thiswflist.append(
                        app.Device(sourceNames[wfIndex]).Waveform())
                self.wflist.append(thiswflist)
            for port in range(snp.simulationNumPorts):
                app.Device(
                    sourceNames[port])['state']['Value'] = stateList[port]

        self.transferMatriceProcessor = si.td.f.TransferMatricesProcessor(
            transferMatrices)
        si.td.wf.Waveform.adaptionStrategy = 'SinX' if SignalIntegrity.App.Preferences[
            'Calculation.UseSinX'] else 'Linear'

        try:
            outputwflist = []
            for port in range(len(self.wflist)):
                outputwflist.append(
                    self.transferMatriceProcessor.ProcessWaveforms(
                        self.wflist[port], adaptToLargest=True))
        except si.SignalIntegrityException as e:
            return None
        #
        # The list of list of input waveforms have been processed processed, generating a list of list of output waveforms in
        # self.outputwflist.  The names of the output waveforms are in snp.m_sd.pOutputList.
        #
        outputwflist = [[
            wf.Adapt(
                si.td.wf.TimeDescriptor(wf.td[wf.td.IndexOfTime(-5e-9)],
                                        fd.TimeDescriptor().K, wf.td.Fs))
            for wf in driven
        ] for driven in outputwflist]

        # The port connection list, which is a list of True or False for each port on the network analyzer, is
        # converted to a list of network port indices corresponding to the driven ports.
        #
        portConnections = []
        for pci in range(len(snp.PortConnectionList)):
            if snp.PortConnectionList[pci]: portConnections.append(pci)

        outputWaveformList = []
        outputWaveformLabels = []
        for r in range(len(outputwflist)):
            wflist = outputwflist[r]
            for c in range(len(wflist)):
                wf = wflist[c]
                wfName = snp.m_sd.pOutputList[c][2]
                gain = gdoDict[wfName]['gain']
                offset = gdoDict[wfName]['offset']
                delay = gdoDict[wfName]['delay']
                if gain != 1.0 or offset != 0.0 or delay != 0.0:
                    wf = wf.DelayBy(delay) * gain + offset
                outputWaveformList.append(wf)
                outputWaveformLabels.append(snp.m_sd.pOutputList[c][2] +
                                            str(portConnections[r] + 1))

        userSampleRate = SignalIntegrity.App.Project[
            'CalculationProperties.UserSampleRate']
        outputWaveformList = [
            wf.Adapt(
                si.td.wf.TimeDescriptor(
                    wf.td.H, int(wf.td.K * userSampleRate / wf.td.Fs),
                    userSampleRate)) for wf in outputWaveformList
        ]

        td = si.td.wf.TimeDescriptor(
            -5e-9,
            SignalIntegrity.App.Project['CalculationProperties.TimePoints'],
            SignalIntegrity.App.Project['CalculationProperties.BaseSampleRate']
        )

        if snp.simulationType != 'CW':
            # note this matrix is transposed from what is normally expected
            Vmat = [[
                outputWaveformList[outputWaveformLabels.index(
                    'V' + str(portConnections[r] + 1) +
                    str(portConnections[c] + 1))]
                for r in range(len(portConnections))
            ] for c in range(len(portConnections))]

            for vli in range(len(Vmat)):
                tdr = si.m.tdr.TDRWaveformToSParameterConverter(
                    WindowForwardHalfWidthTime=200e-12,
                    WindowReverseHalfWidthTime=200e-12,
                    WindowRaisedCosineDuration=50e-12,
                    Step=(snp.simulationType == 'TDRStep'),
                    Length=0,
                    Denoise=True,
                    DenoisePercent=20.,
                    Inverted=False,
                    fd=td.FrequencyList())

                tdr.Convert(Vmat[vli], vli)
                for r in range(len(portConnections)):
                    outputWaveformList.append(tdr.IncidentWaveform if r ==
                                              vli else si.td.wf.Waveform(td))
                    outputWaveformLabels.append('A' +
                                                str(portConnections[r] + 1) +
                                                str(portConnections[vli] + 1))
                for r in range(len(portConnections)):
                    outputWaveformList.append(tdr.ReflectWaveforms[r])
                    outputWaveformLabels.append('B' +
                                                str(portConnections[r] + 1) +
                                                str(portConnections[vli] + 1))

        if not SParameters:
            return (sourceNames, outputWaveformLabels, transferMatrices,
                    outputWaveformList)
        else:
            # waveforms are adapted this way to give the horizontal offset that it already has closest to
            #-5 ns, with the correct number of points without resampling the waveform in any way.
            frequencyContentList = []
            for wf in outputWaveformList:
                td = si.td.wf.TimeDescriptor(
                    -5e-9, SignalIntegrity.App.
                    Project['CalculationProperties.TimePoints'],
                    SignalIntegrity.App.
                    Project['CalculationProperties.BaseSampleRate'])
                td.H = wf.TimeDescriptor()[wf.TimeDescriptor().IndexOfTime(
                    td.H)]
                fc = wf.Adapt(td).FrequencyContent()
                frequencyContentList.append(fc)

            Afc = [[
                frequencyContentList[outputWaveformLabels.index(
                    'A' + str(portConnections[r] + 1) +
                    str(portConnections[c] + 1))]
                for c in range(len(portConnections))
            ] for r in range(len(portConnections))]
            Bfc = [[
                frequencyContentList[outputWaveformLabels.index(
                    'B' + str(portConnections[r] + 1) +
                    str(portConnections[c] + 1))]
                for c in range(len(portConnections))
            ] for r in range(len(portConnections))]

            from numpy import array
            from numpy.linalg import inv

            frequencyList = td.FrequencyList()
            data = [None for _ in range(len(frequencyList))]
            for n in range(len(frequencyList)):
                B = [[Bfc[r][c][n] for c in range(snp.simulationNumPorts)]
                     for r in range(snp.simulationNumPorts)]
                A = [[Afc[r][c][n] for c in range(snp.simulationNumPorts)]
                     for r in range(snp.simulationNumPorts)]
                data[n] = (array(B).dot(inv(array(A)))).tolist()
            sp = si.sp.SParameters(frequencyList, data)
            return sp