Exemple #1
0
    def PlotWaveformsTimeDomain(self):
        self.lift(self.parent.parent)
        self.plt.cla()
        self.plt.set_ylabel('amplitude', fontsize=10)
        self.plotLabel.config(text='Time-domain View')

        if not SignalIntegrity.App.Preferences['Appearance.PlotCursorValues']:
            self.plt.format_coord = lambda x, y: ''

        if not self.waveformList == None:
            self.plt.autoscale(False)

        mint = None
        maxt = None
        for wfi in range(len(self.waveformList)):
            wf = self.waveformList[wfi]
            wfTimes = wf.Times()
            if len(wfTimes) == 0:
                continue
            wfValues = wf.Values()
            wfName = str(self.waveformNamesList[wfi])
            mint = wfTimes[0] if mint is None else min(mint, wfTimes[0])
            maxt = wfTimes[-1] if maxt is None else max(maxt, wfTimes[-1])

        timeLabel = 's'
        timeLabelDivisor = 1.
        if not self.waveformList is None:
            if (not mint is None) and (not maxt is None):
                durLabelTime = (maxt - mint)
                timeLabel = ToSI(durLabelTime, 's')[-2:]
                timeLabelDivisor = FromSI('1. ' + timeLabel, 's')
                mint = mint / timeLabelDivisor
                maxt = maxt / timeLabelDivisor
            if not mint is None:
                self.plt.set_xlim(left=mint)
            if not maxt is None:
                self.plt.set_xlim(right=maxt)

        minv = None
        maxv = None
        for wfi in range(len(self.waveformList)):
            wf = self.waveformList[wfi]
            wfTimes = wf.Times(timeLabelDivisor)
            if len(wfTimes) == 0:
                continue
            wfValues = wf.Values()
            wfName = str(self.waveformNamesList[wfi])
            self.plt.plot(wfTimes, wfValues, label=wfName)
            minv = min(wfValues) if minv is None else min(minv, min(wfValues))
            maxv = max(wfValues) if maxv is None else max(maxv, max(wfValues))

        self.plt.set_xlabel('time (' + timeLabel + ')', fontsize=10)
        self.plt.legend(loc='upper right', labelspacing=0.1)

        self.plt.set_ylim(bottom=minv)
        self.plt.set_ylim(top=maxv)

        self.f.canvas.draw()
        return self
 def SetValueFromString(self, string):
     if self['Type'] == 'string' or self['Type'] == 'enum':
         self['Value'] = str(string)
     elif self.GetValue('Type') == 'file':
         self['Value'] = str(string)
     elif self.GetValue('Type') == 'int':
         try:
             self['Value'] = int(string)
         except ValueError:
             self['Value'] = 0
     elif self['Type'] == 'float':
         value = FromSI(string, self['Unit'])
         if value is not None:
             self['Value'] = value
     else:
         raise ValueError
         self['Value'] = str(string)
     return self
    def UpdateMeasurements(self, measDict):
        if (measDict is None) or (not 'Bathtub' in measDict.keys()):
            self.withdraw()
            return
        self.dialogFrame.pack_forget()
        self.dialogFrame = tk.Frame(self, borderwidth=5)
        self.dialogFrame.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
        leftFrame = tk.Frame(self.dialogFrame)
        leftFrame.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES)
        rightFrame = tk.Frame(self.dialogFrame)
        rightFrame.pack(side=tk.LEFT,
                        fill=tk.BOTH,
                        expand=tk.YES,
                        anchor=tk.NW)
        leftPlotFrame = tk.Frame(leftFrame)
        leftPlotFrame.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES)
        self.leftLabel = tk.Label(leftPlotFrame, fg='black')
        self.leftLabel.pack(fill=tk.X)
        numberOfEyes = len(measDict['Eye'])
        rightPlotFrames = [tk.Frame(rightFrame) for _ in range(numberOfEyes)]
        self.rightPlotLabels = [None for _ in range(numberOfEyes)]
        for e in range(numberOfEyes):
            rightPlotFrames[e].pack(side=tk.TOP,
                                    fill=tk.BOTH,
                                    expand=tk.YES,
                                    anchor=tk.NW)
            self.rightPlotLabels[e] = tk.Label(rightPlotFrames[e], fg='black')
            self.rightPlotLabels[e].pack(fill=tk.X)

        plotWidth = SignalIntegrity.App.Preferences['Appearance.PlotWidth']
        plotHeight = SignalIntegrity.App.Preferences['Appearance.PlotHeight']
        plotDPI = SignalIntegrity.App.Preferences['Appearance.PlotDPI']

        self.leftFigure = Figure(figsize=(plotWidth, plotHeight), dpi=plotDPI)
        self.leftPlot = self.leftFigure.add_subplot(111)
        self.leftCanvas = FigureCanvasTkAgg(self.leftFigure,
                                            master=leftPlotFrame)
        self.leftCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.X, expand=1)
        self.leftToolbar = NavigationToolbar(self.leftCanvas, leftPlotFrame,
                                             self.onLeftHome)
        self.leftToolbar.update()
        self.leftCanvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.leftToolbar.pan()

        self.rightFigures = [
            Figure(figsize=(plotWidth, plotHeight), dpi=plotDPI)
            for e in range(numberOfEyes)
        ]
        self.rightPlots = [None for e in range(numberOfEyes)]
        self.rightCanvases = [None for e in range(numberOfEyes)]
        self.rightToolbars = [None for e in range(numberOfEyes)]

        for e in range(numberOfEyes):
            self.rightPlots[e] = self.rightFigures[e].add_subplot(111)
            self.rightCanvases[e] = FigureCanvasTkAgg(
                self.rightFigures[e], master=rightPlotFrames[e])
            self.rightCanvases[e].get_tk_widget().pack(side=tk.TOP,
                                                       fill=tk.X,
                                                       expand=1)
            self.rightToolbars[e] = NavigationToolbar(self.rightCanvases[e],
                                                      rightPlotFrames[e],
                                                      self.onRightHome)
            self.rightToolbars[e].update()
            self.rightCanvases[e]._tkcanvas.pack(side=tk.TOP,
                                                 fill=tk.BOTH,
                                                 expand=1)
            self.rightToolbars[e].pan()

        self.leftPlot.cla()
        for e in range(len(self.rightPlots)):
            self.rightPlots[e].cla()

        if not SignalIntegrity.App.Preferences['Appearance.PlotCursorValues']:
            self.leftPlot.format_coord = lambda x, y: ''
            for e in range(len(self.rightPlots)):
                self.rightPlots[e].format_coord = lambda x, y: ''

        wf = measDict['Bathtub']['Vertical']['Data']
        x = wf['x']
        y = wf['y']

        self.voltLabel = ' ' + ToSI(x[-1], 'V').split(' ')[-1]
        voltLabelDivisor = FromSI('1. ' + self.voltLabel, 'V')

        x = [v / voltLabelDivisor for v in x]

        lowerLimit = 1e-30
        try:
            wf = measDict['Bathtub']['Vertical']['Level'][0]['LeftEst']['Est'][
                'Wf']
            if not wf is None:
                self.leftPlot.semilogy([v / voltLabelDivisor for v in wf['x']],
                                       wf['y'],
                                       color='green',
                                       linewidth=6)
        except Exception as ex:
            print(ex)

        try:
            wf = measDict['Bathtub']['Vertical']['Level'][numberOfEyes][
                'RightEst']['Est']['Wf']
            if not wf is None:
                self.leftPlot.semilogy([v / voltLabelDivisor for v in wf['x']],
                                       wf['y'],
                                       color='green',
                                       linewidth=6)
        except Exception as ex:
            print(ex)

        for e in range(len(measDict['Bathtub']['Vertical']['Level'])):
            try:
                wf = measDict['Bathtub']['Vertical']['Level'][e]['RightEst'][
                    'Est']['Wf']
                if not wf is None:
                    self.leftPlot.semilogy(
                        [v / voltLabelDivisor for v in wf['x']],
                        wf['y'],
                        color='green',
                        linewidth=6)
            except Exception as ex:
                print(ex)
            try:
                wf = measDict['Bathtub']['Vertical']['Level'][e]['LeftEst'][
                    'Est']['Wf']
                if not wf is None:
                    self.leftPlot.semilogy(
                        [v / voltLabelDivisor for v in wf['x']],
                        wf['y'],
                        color='green',
                        linewidth=6)
            except Exception as ex:
                print(ex)
        # now, gather all of the curve fits and actual data into probability histograms that span the entire
        # eye
        for t in range(numberOfEyes + 1):
            try:
                # probablity histogram
                yCombo = measDict['Bathtub']['Vertical']['Level'][t]['Hist']
                self.leftPlot.semilogy(
                    x, [np.nan if v < lowerLimit else v for v in yCombo],
                    color='green',
                    linewidth=3)
                # compute the CDF from the left and the right
                self.leftPlot.semilogy(x, [
                    np.nan if v < lowerLimit else v for v in
                    measDict['Bathtub']['Vertical']['Level'][t]['CDFFromLeft']
                ],
                                       color='red')
                self.leftPlot.semilogy(x, [
                    np.nan if v < lowerLimit else v for v in
                    measDict['Bathtub']['Vertical']['Level'][t]['CDFFromRight']
                ],
                                       color='red')
            except Exception as ex:
                print(ex)
                pass

        y = [v if v != 0 else np.nan for v in y]
        self.leftPlot.semilogy(x, y, color='blue')

        for e in range(len(measDict['Eye'])):
            self.leftPlot.axvline(x=measDict['Eye'][e]['Decision']['Volt'] /
                                  voltLabelDivisor,
                                  color='red',
                                  linestyle='--')

        self.leftLabel.config(text='Vertical Bathtub Curve')

        self.leftPlot.set_ylabel('probability', fontsize=10)
        self.leftPlot.set_xlabel('voltage (' + self.voltLabel + ')',
                                 fontsize=10)

        self.leftPlot.grid(True, 'both')

        for ee in range(len(measDict['Bathtub']['Horizontal'])):
            e = numberOfEyes - 1 - ee

            wf = measDict['Bathtub']['Horizontal'][e]['Data']
            x = wf.Times()
            y = wf.Values()

            self.timeLabel = ToSI(x[-1], 's')[-3:]
            timeLabelDivisor = FromSI('1. ' + self.timeLabel, 's')

            x = [v / timeLabelDivisor for v in x]
            y = [v if v != 0 else np.nan for v in y]
            self.rightPlots[ee].semilogy(x, y)
            self.rightPlots[ee].axvline(x=0.0, color='red', linestyle='--')

            self.rightPlotLabels[ee].config(
                text='Horizontal Bathtub Curve' +
                (f' for Eye {e}'
                 if len(measDict['Bathtub']['Horizontal']) > 1 else ''))

            self.rightPlots[ee].set_ylabel('probability', fontsize=10)
            self.rightPlots[ee].set_xlabel('time (' + self.timeLabel + ')',
                                           fontsize=10)

            self.rightPlots[ee].grid(True, 'both')
        self.deiconify()
 def GetString(self):
     return FromSI(self.string.get(), self.unitString)
Exemple #5
0
    def PlotWaveformsTimeDomain(self):
        self.lift(self.parent.parent)
        self.plt.cla()
        self.plt.set_ylabel('amplitude',fontsize=10)
        self.plotLabel.config(text='Time-domain View')

        if not SignalIntegrity.App.Preferences['Appearance.PlotCursorValues']:
            self.plt.format_coord = lambda x, y: ''

        if not self.waveformList == None:
            self.plt.autoscale(False)

        mint=None
        maxt=None
        for wfi in range(len(self.waveformList)):
            wf=self.waveformList[wfi]
            wfTimes=wf.Times()
            if len(wfTimes)==0:
                continue
            wfValues=wf.Values()
            wfName=str(self.waveformNamesList[wfi])
            mint=wfTimes[0] if mint is None else min(mint,wfTimes[0])
            maxt=wfTimes[-1] if maxt is None else max(maxt,wfTimes[-1])

        timeLabel='s'
        timeLabelDivisor=1.
        if not self.waveformList is None:
            if (not mint is None) and (not maxt is None):
                durLabelTime=(maxt-mint)
                timeLabel=ToSI(durLabelTime,'s')[-2:]
                timeLabelDivisor=FromSI('1. '+timeLabel,'s')
                mint=mint/timeLabelDivisor
                maxt=maxt/timeLabelDivisor

        if not self.ZoomsInitialized:
            self.minx=mint
            self.maxx=maxt

        if self.minx != None:
            self.plt.set_xlim(left=self.minx)

        if self.maxx != None:
            self.plt.set_xlim(right=self.maxx)

        minv=None
        maxv=None
        for wfi in range(len(self.waveformList)):
            wf=self.waveformList[wfi]
            wfTimes=wf.Times(timeLabelDivisor)
            if len(wfTimes)==0:
                continue
            wfValues=wf.Values()
            wfName=str(self.waveformNamesList[wfi])
            wfColor=self.waveformColorIndexList[wfi]
            plotlog=False
            plotdB=False
            if plotlog:
                self.plt.semilogy(wfTimes,wf.Values('abs'),label=wfName,c=wfColor)
            elif plotdB:
                self.plt.plot(wfTimes,[max(20.*math.log10(abs(a)),-200.) for a in wf.Values('abs')],label=wfName,c=wfColor)
            else:
                self.plt.plot(wfTimes,wfValues,label=wfName,c=wfColor)
            minv=min(wfValues) if minv is None else min(minv,min(wfValues))
            maxv=max(wfValues) if maxv is None else max(maxv,max(wfValues))

        self.plt.set_xlabel('time ('+timeLabel+')',fontsize=10)
        self.plt.legend(loc='upper right',labelspacing=0.1)

        if not self.ZoomsInitialized:
            self.miny=minv
            self.maxy=maxv

        if self.miny != None:
            self.plt.set_ylim(bottom=self.miny)

        if self.maxy != None:
            self.plt.set_ylim(top=self.maxy)

        if self.ShowGridsDoer.Bool():
            self.plt.grid(True)

        self.ZoomsInitialized=True
        self.f.canvas.draw()

        self.plt.callbacks.connect('xlim_changed', self.onXLimitChange)
        self.plt.callbacks.connect('ylim_changed', self.onYLimitChange)

        return self
Exemple #6
0
    def PlotWaveformsFrequencyContent(self,density=False):
        self.lift(self.parent.parent)
        self.plt.cla()

        if not SignalIntegrity.App.Preferences['Appearance.PlotCursorValues']:
            self.plt.format_coord = lambda x, y: ''

        if not self.waveformList == None:
            self.plt.autoscale(False)

        self.frequencyContentList=[wf.FrequencyContent().LimitEndFrequency(SignalIntegrity.App.Project['CalculationProperties.EndFrequency'])
            for wf in self.waveformList]

        minf=None
        maxf=None
        for wfi in range(len(self.waveformList)):
            fc=self.frequencyContentList[wfi]
            fcFrequencies=fc.Frequencies()
            if len(fcFrequencies)==0:
                continue
            fcValues=fc.Values('dBm')
            fcName=str(self.waveformNamesList[wfi])
            minf=fcFrequencies[0] if minf is None else min(minf,fcFrequencies[0])
            maxf=fcFrequencies[-1] if maxf is None else max(maxf,fcFrequencies[-1])

        freqLabel='Hz'
        freqLabelDivisor=1.
        if not self.waveformList is None:
            if (not minf is None) and (not maxf is None):
                durLabelFrequency=(maxf-minf)
                freqLabel=ToSI(durLabelFrequency,'Hz')[-3:]
                freqLabelDivisor=FromSI('1. '+freqLabel,'Hz')
                minf=minf/freqLabelDivisor
                maxf=maxf/freqLabelDivisor

            if not self.ZoomsInitialized:
                self.minx=minf
                self.maxx=maxf

            if self.LogScaleDoer.Bool():
                if self.minx <= 0.:
                    if max(fcFrequencies)>0:
                        for value in fcFrequencies:
                            if value>0.:
                                self.minx=value/freqLabelDivisor
                                break

            if self.minx != None:
                self.plt.set_xlim(left=self.minx)

            if self.maxx != None:
                self.plt.set_xlim(right=self.maxx)

        if density:
            self.plotLabel.config(text='Spectral Density')
            self.plt.set_ylabel('magnitude (dBm/'+freqLabel+')',fontsize=10)
        else:
            self.plotLabel.config(text='Spectral Content')
            self.plt.set_ylabel('magnitude (dBm)',fontsize=10)

        minv=None
        maxv=None
        minvStd=None
        for wfi in range(len(self.frequencyContentList)):
            fc=self.frequencyContentList[wfi]
            fcFrequencies=fc.Frequencies(freqLabelDivisor)
            if len(fcFrequencies)==0:
                continue
            if density:
                adder=10.*math.log10(freqLabelDivisor)
                fcValues=[v+adder for v in fc.Values('dBmPerHz')]
            else:
                fcValues=fc.Values('dBm')
            minv=min(fcValues) if minv is None else min(minv,min(fcValues))
            maxv=max(fcValues) if maxv is None else max(maxv,max(fcValues))
            minvStd=mean(fcValues)-0.5*std(fcValues) if minvStd is None else min(minvStd,mean(fcValues)-0.5*std(fcValues))

            fcName=str(self.waveformNamesList[wfi])
            fcColor=self.waveformColorIndexList[wfi]

            if self.LogScaleDoer.Bool():
                self.plt.semilogx(fcFrequencies,fcValues,label=fcName,c=fcColor)
            else:
                self.plt.plot(fcFrequencies,fcValues,label=fcName,c=fcColor)

        if minv != None or minvStd != None:
            minv = max(minv,minvStd)

        self.plt.set_xlabel('frequency ('+freqLabel+')',fontsize=10)
        self.plt.legend(loc='upper right',labelspacing=0.1)

        if not self.ZoomsInitialized:
            self.miny=minv
            self.maxy=maxv

        if self.miny != None:
            self.plt.set_ylim(bottom=self.miny)
        if self.maxy != None:
            self.plt.set_ylim(top=self.maxy)

        if self.ShowGridsDoer.Bool():
            self.plt.grid(True, 'both')

        self.ZoomsInitialized=True
        self.f.canvas.draw()

        self.plt.callbacks.connect('xlim_changed', self.onXLimitChange)
        self.plt.callbacks.connect('ylim_changed', self.onYLimitChange)

        return self
Exemple #7
0
    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 PlotWaveformsFrequencyContent(self, density=False):
        self.lift(self.parent.parent)
        self.plt.cla()

        import SignalIntegrity.Lib as si
        fd = si.fd.EvenlySpacedFrequencyList(
            SignalIntegrity.App.Project['CalculationProperties.EndFrequency'],
            SignalIntegrity.App.
            Project['CalculationProperties.FrequencyPoints'])

        if not SignalIntegrity.App.Preferences['Appearance.PlotCursorValues']:
            self.plt.format_coord = lambda x, y: ''

        if not self.waveformList == None:
            self.plt.autoscale(False)

        self.frequencyContentList = [
            wf.FrequencyContent().LimitEndFrequency(
                SignalIntegrity.App.
                Project['CalculationProperties.EndFrequency'])
            for wf in self.waveformList
        ]

        minf = None
        maxf = None
        for wfi in range(len(self.waveformList)):
            fc = self.frequencyContentList[wfi]
            fcFrequencies = fc.Frequencies()
            if len(fcFrequencies) == 0:
                continue
            fcValues = fc.Values('dBm')
            fcName = str(self.waveformNamesList[wfi])
            minf = fcFrequencies[0] if minf is None else min(
                minf, fcFrequencies[0])
            maxf = fcFrequencies[-1] if maxf is None else max(
                maxf, fcFrequencies[-1])

        freqLabel = 'Hz'
        freqLabelDivisor = 1.
        if not self.waveformList is None:
            if (not minf is None) and (not maxf is None):
                durLabelFrequency = (maxf - minf)
                freqLabel = ToSI(durLabelFrequency, 'Hz')[-3:]
                freqLabelDivisor = FromSI('1. ' + freqLabel, 'Hz')
                minf = minf / freqLabelDivisor
                maxf = maxf / freqLabelDivisor
            if not minf is None:
                self.plt.set_xlim(left=minf)
            if not maxf is None:
                self.plt.set_xlim(right=maxf)

        if density:
            self.plotLabel.config(text='Spectral Density')
            self.plt.set_ylabel('magnitude (dBm/' + freqLabel + ')',
                                fontsize=10)
        else:
            self.plotLabel.config(text='Spectral Content')
            self.plt.set_ylabel('magnitude (dBm)', fontsize=10)

        minv = None
        maxv = None
        minvStd = None
        for wfi in range(len(self.frequencyContentList)):
            fc = self.frequencyContentList[wfi]
            fcFrequencies = fc.Frequencies(freqLabelDivisor)
            if len(fcFrequencies) == 0:
                continue
            if density:
                adder = 10. * math.log10(freqLabelDivisor)
                fcValues = [v + adder for v in fc.Values('dBmPerHz')]
            else:
                fcValues = fc.Values('dBm')
            minv = min(fcValues) if minv is None else min(minv, min(fcValues))
            maxv = max(fcValues) if maxv is None else max(maxv, max(fcValues))
            minvStd = mean(
                fcValues) - 0.5 * std(fcValues) if minvStd is None else min(
                    minvStd,
                    mean(fcValues) - 0.5 * std(fcValues))

            fcName = str(self.waveformNamesList[wfi])
            self.plt.plot(fcFrequencies, fcValues, label=fcName)

        minv = max(minv, minvStd)

        self.plt.set_xlabel('frequency (' + freqLabel + ')', fontsize=10)
        self.plt.legend(loc='upper right', labelspacing=0.1)

        self.plt.set_ylim(bottom=minv)
        self.plt.set_ylim(top=maxv)

        self.f.canvas.draw()
        return self