示例#1
0
 def Preliminary(self,filename,checkPicture=True,checkNetlist=True):
     os.chdir(self.path)
     from SignalIntegrity.App.SignalIntegrityAppHeadless import SignalIntegrityAppHeadless
     pysi=SignalIntegrityAppHeadless()
     self.assertTrue(pysi.OpenProjectFile(os.path.realpath(filename)),filename + ' couldnt be opened')
     if checkPicture:
         self.PictureChecker(pysi,filename)
     if checkNetlist:
         self.NetListChecker(pysi,filename)
     return pysi
    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