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)
Ejemplo n.º 2
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