def __init__(self,wfl):
        """Constructor

        insternally adapts all of the waveforms provided and keeps them internally in
        a list.

        @param wfl list of instances of class Waveform to be adapted
        """
        from SignalIntegrity.Lib.TimeDomain.Filters.WaveformTrimmer import WaveformTrimmer
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorSinX import InterpolatorSinX
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorSinX import FractionalDelayFilterSinX
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorLinear import InterpolatorLinear
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorLinear import FractionalDelayFilterLinear
        strategy=wfl[0].adaptionStrategy
        #upsample all of the waveforms first
        ufl=[int(round(wfl[0].td.Fs/wf.td.Fs)) for wf in wfl]
        wfl=[wf if uf == 1 else wf*
            (InterpolatorSinX(uf) if strategy=='SinX' else InterpolatorLinear(uf))
            for (uf,wf) in zip(ufl,wfl)]
        adl=[wfl[0].td/wf.td for wf in wfl]
        fdl=[ad.D-int(ad.D) for ad in adl]
        wfl=[wf if fd == 0.0 else wf*
            (FractionalDelayFilterSinX(fd,True) if strategy=='SinX' else FractionalDelayFilterLinear(fd,True))
            for (fd,wf) in zip(fdl,wfl)]
        overlapping=wfl[0].td
        for wf in wfl[1:]: overlapping=overlapping.Intersection(wf.td)
        # overlapping now contains the overlapping waveform
        adl=[overlapping/wf.td for wf in wfl]
        trl=[WaveformTrimmer(max(0,int(round(ad.TrimLeft()))),max(0,int(round(ad.TrimRight())))) for ad in adl]
        list.__init__(self,[wf*tr for (wf,tr) in zip(wfl,trl)])
 def DenoisedWaveform(wf, pct=30., mult=5., isDerivative=True):
     """
     Denoises a waveform.
     @details The noise is estimated by the amount of noise in the last pct percent of the
     last scale of the wavelet transform.  The threshold is set as a multiplier on
     the noise, generally 5 is used.  Thus wavelets more than 5 times the noise floor
     are kept, while all others are deleted (this is called hard-thresholding).\n
     Usually this algorithm is used to denoise TDR waveforms, which are usually steps
     and the denoising is performed on the derivative of the step waveform.  Therefore,
     the noise threshold needs to be shaped based on the effect of the derivative on
     the noise shape.  For impulsive waveforms, no derivative is performed and
     isDerivative is set to False, causing a white noise threshold to be assumed.
     @param wf instance of class Waveform to be denoised.
     @param pct (optional) float percentage (defaults to 30).
     @param mult (optional) float noise multiplier for threshold (defaults to 5).
     @param isDerivative (optional) bool whether the waveform is a derivative
     (defaults to True).
     @return the denoised waveform.
     @remark the algorithm assumes there is no signal in the last pct percent
     of the last scale of the dwt
     @see Wavelet
     """
     w = WaveletDenoiser.wavelet
     Ki = wf.td.K
     Kf = int(pow(2, math.ceil(log2(wf.td.K))))
     PadLeft = Kf - Ki
     pct = pct * Ki / Kf
     pwf = wf * WaveformTrimmer(-PadLeft, 0)
     X = w.DWT(pwf.Values())
     T = WaveletDenoiser.DerivativeThresholdCalc(X, w.h, pct, isDerivative)
     # pragma: silent exclude
     #         import matplotlib.pyplot as plt
     #         plt.clf()
     #         plt.title('denoising')
     #         plt.loglog([k for k in range(len(X))],[abs(x) for x in X],label='dwt')
     #         plt.loglog([k for k in range(len(X))],[t*mult for t in T],label='threshold')
     #         plt.xlabel('samples')
     #         plt.ylabel('amplitude')
     #         plt.legend(loc='upper right')
     #         plt.grid(True)
     #         plt.show()
     # pragma: include
     dwf = Waveform(
         pwf.td,
         w.IDWT([0 if abs(x) < t * mult else x for (x, t) in zip(X, T)]))
     return dwf * WaveformTrimmer(PadLeft, 0)
    def Adapt(self, td):
        """adapts waveform to time descriptor

        Waveform adaption is performed using upsampling, decimation, fractional delay,
        and waveform point trimming.

        @param td instance of class TimeDescriptor to adapt waveform to
        @return instance of class Waveform containing self adapted to the time descriptor
        @note does not affect self.
        @note the static member variable adaptionStrategy determines how to interpolate.  'SinX' means
        to use sinx/x interpolation, 'Linear' means to use linear interpolation.
        @see InterpolatorSinX
        @see SignalIntegrity.TimeDomain.Filters.InterpolatorSinX.FractionalDelayFilterSinX
        @see SignalIntegrity.TimeDomain.Filters.InterpolatorSinX.FractionalDelayFilterSinX
        @see SignalIntegrity.TimeDomain.Filters.InterpolatorLinear.InterpolatorLinear
        @see SignalIntegrity.TimeDomain.Filters.InterpolatorLinear.FractionalDelayFilterLinear
        @see SignalIntegrity.TimeDomain.Filters.WaveformTrimmer.WaveformTrimmer
        @see SignalIntegrity.TimeDomain.Filters.WaveformDecimator.WaveformDecimator
        @see SignalIntegrity.Rat.Rat

        """
        # pragma: silent exclude
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorSinX import InterpolatorSinX
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorSinX import FractionalDelayFilterSinX
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorLinear import InterpolatorLinear
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorLinear import FractionalDelayFilterLinear
        from SignalIntegrity.Lib.TimeDomain.Filters.WaveformTrimmer import WaveformTrimmer
        from SignalIntegrity.Lib.TimeDomain.Filters.WaveformDecimator import WaveformDecimator
        from SignalIntegrity.Lib.Rat import Rat
        # pragma: include
        wf = self
        (upsampleFactor, decimationFactor) = Rat(td.Fs / wf.td.Fs)
        if upsampleFactor > 1:
            wf = wf * (InterpolatorSinX(upsampleFactor) if wf.adaptionStrategy
                       == 'SinX' else InterpolatorLinear(upsampleFactor))
        ad = td / wf.td
        f = ad.D - int(ad.D)
        if not f == 0.0:
            wf = wf * (FractionalDelayFilterSinX(f, True)
                       if wf.adaptionStrategy == 'SinX' else
                       FractionalDelayFilterLinear(f, True))
            ad = td / wf.td
        if decimationFactor > 1:
            decimationPhase = int(round(ad.TrimLeft())) % decimationFactor
            wf = wf * WaveformDecimator(decimationFactor, decimationPhase)
            ad = td / wf.td
        tr = WaveformTrimmer(max(0, int(round(ad.TrimLeft()))),
                             max(0, int(round(ad.TrimRight()))))
        wf = wf * tr
        return wf
示例#4
0
    def __init__(self, wfl):
        """Constructor  
        insternally adapts all of the waveforms provided and keeps them internally in
        a list.
        @param wfl list of instances of class Waveform to be adapted
        """
        from SignalIntegrity.Lib.TimeDomain.Filters.WaveformTrimmer import WaveformTrimmer
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorSinX import InterpolatorSinX
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorSinX import FractionalDelayFilterSinX
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorLinear import InterpolatorLinear
        from SignalIntegrity.Lib.TimeDomain.Filters.InterpolatorLinear import FractionalDelayFilterLinear
        from SignalIntegrity.Lib.Rat import Rat
        strategy = wfl[0].adaptionStrategy

        #upsample all of the waveforms first
        # udfl is a list of (U,D) tuples containing upsample and decimation factor
        # todo: this change was made to prevent a failure, presumably when decimation was needed (and would
        # create an integer upsample factor of 0).  Now, for example, it might have an upsample factor of 1 and
        # a downsample factor of 2, instead of 0 for the integer upsample factor, which caused failure.  But, it's
        # unclear how the downsample factor is handled downstream of this and this needs to be investigated.
        # in any case, all the unit tests pass with this change.
        udfl = [Rat(wfl[0].td.Fs / wf.td.Fs) for wf in wfl]
        wfl = [
            wf if uf[0] == 1 else wf * (InterpolatorSinX(
                uf[0]) if strategy == 'SinX' else InterpolatorLinear(uf[0]))
            for (uf, wf) in zip(udfl, wfl)
        ]
        adl = [wfl[0].td / wf.td for wf in wfl]
        fdl = [ad.D - int(ad.D) for ad in adl]
        wfl = [
            wf if fd == 0.0 else wf *
            (FractionalDelayFilterSinX(fd, True)
             if strategy == 'SinX' else FractionalDelayFilterLinear(fd, True))
            for (fd, wf) in zip(fdl, wfl)
        ]
        overlapping = wfl[0].td
        for wf in wfl[1:]:
            overlapping = overlapping.Intersection(wf.td)
        # overlapping now contains the overlapping waveform
        adl = [overlapping / wf.td for wf in wfl]
        trl = [
            WaveformTrimmer(max(0, int(round(ad.TrimLeft()))),
                            max(0, int(round(ad.TrimRight())))) for ad in adl
        ]
        list.__init__(self, [wf * tr for (wf, tr) in zip(wfl, trl)])