Exemple #1
0
    def SimAperture(self, sz, rad_x, rad_y=None, *, shape='cir'):
        ## Initialize ##
        # Create the Lateral meshes #
        xx, yy = np.meshgrid(*_MeshLat(*sz, shift=True))

        # Determine boundaries #
        if ((shape.lower in ('cir', 'sqr'))
                or (rad_y is None)):  # Isotropic, only first input #
            rad_y = rad_x

        # Transform the aperture into pixels, and un-normalize the sinc functions #
        rad_x /= USER.RES[0] / (np.pi / 2)
        rad_y /= USER.RES[1] / (np.pi / 2)

        # Check if lobes need to be puffed up a bit (I don't know why?) #
        #if((USER.KER_TYPE == PM.HELIX) and (USER.KER_Z > 1)):
        #	rad_x *= 4/3
        #	rad_y *= 4/3

        ## Calculate Aperture ##
        # We work with the Fourier transform directly to prevent edge effects #
        if (shape.lower() in ('cir', 'ell')):
            apr = sp.sinc(np.sqrt((xx / rad_x)**2 + (yy / rad_y)**2))
        elif (shape.lower() in ('sqr', 'rec')):
            apr = sp.sinc(xx / rad_x) + sp.sinc(yy / rad_y)

        ## Output ##
        return apr
Exemple #2
0
def slepian(M, width, sym=True):
    """Return the M-point slepian window.

    """
    if (M * width > 27.38):
        raise ValueError("Cannot reliably obtain slepian sequences for"
              " M*width > 27.38.")
    if M < 1:
        return np.array([])
    if M == 1:
        return np.ones(1, 'd')
    odd = M % 2
    if not sym and not odd:
        M = M + 1

    twoF = width / 2.0
    alpha = (M - 1) / 2.0
    m = np.arange(0, M) - alpha
    n = m[:, np.newaxis]
    k = m[np.newaxis, :]
    AF = twoF * special.sinc(twoF * (n - k))
    [lam, vec] = linalg.eig(AF)
    ind = np.argmax(abs(lam), axis=-1)
    w = np.abs(vec[:, ind])
    w = w / max(w)

    if not sym and not odd:
        w = w[:-1]
    return w
Exemple #3
0
def slepian(M,width,sym=1):
    """Return the M-point slepian window.

    """
    if (M*width > 27.38):
        raise ValueError, "Cannot reliably obtain slepian sequences for"\
              " M*width > 27.38."
    if M < 1:
        return array([])
    if M == 1:
        return ones(1,'d')
    odd = M % 2
    if not sym and not odd:
        M = M+1

    twoF = width/2.0
    alpha = (M-1)/2.0
    m = arange(0,M)-alpha
    n = m[:,newaxis]
    k = m[newaxis,:]
    AF = twoF*special.sinc(twoF*(n-k))
    [lam,vec] = linalg.eig(AF)
    ind = argmax(abs(lam),axis=-1)
    w = abs(vec[:,ind])
    w = w / max(w)

    if not sym and not odd:
        w = w[:-1]
    return w
Exemple #4
0
 def __calc_amplitude_on_meshgrid_one_harmonic(self, harmonic):
     x_2D = self.x_2D
     y_2D = self.y_2D
     r2_2D = self.gamma**2 * (x_2D**2 + y_2D**2)
     A = self.wiggler.aux_const + r2_2D
     Y = harmonic * self.wiggler.K_peak**2 / 4 / A
     X = 2 * harmonic * self.gamma * self.wiggler.K_peak * x_2D / A
     sum1 = 0
     sum2 = 0
     sum3 = 0
     p = -self.bessel_cutoff
     jv2pm1 = jv(harmonic + 2 * p - 1, X)
     for p in range(-self.bessel_cutoff, self.bessel_cutoff + 1):
         jvpY = jv(p, Y)
         sum1 += jv(harmonic + 2 * p, X) * jvpY
         sum2 += jv2pm1 * jvpY
         jv2pp1 = jv(harmonic + 2 * p + 1, X)
         sum3 += jv2pp1 * jvpY
         jv2pm1 = jv2pp1
     aux_factor = np.sqrt(self.alpha)*harmonic*self.gamma\
         * self.wiggler.N_periods/ A
     bessel_part_x = aux_factor \
         * (2*self.gamma*x_2D*sum1
                       - self.wiggler.K_peak*(sum2+sum3))
     bessel_part_y = aux_factor * 2 * self.gamma * y_2D * sum1
     dw_arr = self.lambda1_um / self.lambda_range - harmonic
     L = [(sinc(self.wiggler.N_periods *
                (harmonic * r2_2D + dw * A) / self.wiggler.aux_const)) /
          np.sqrt(l) * np.sqrt(st) for dw, l, st in zip(
              dw_arr, self.lambda_range, self.spectral_transmission)]
     L = np.asarray(L)
     return bessel_part_x * L, bessel_part_y * L
def firwin(N, cutoff, width=None, window='hamming'):
    """
    FIR Filter Design using windowed ideal filter method.

    Parameters
    ----------
    N      -- order of filter (number of taps)
    cutoff -- cutoff frequency of filter (normalized so that 1 corresponds to
              Nyquist or pi radians / sample)

    width  -- if width is not None, then assume it is the approximate width of
              the transition region (normalized so that 1 corresonds to pi)
              for use in kaiser FIR filter design.
    window -- desired window to use. See get_window for a list
              of windows and required parameters.

    Returns
    -------
    h      -- coefficients of length N fir filter.

    """

    from signaltools import get_window
    if isinstance(width,float):
        A = 2.285*N*width + 8
        if (A < 21): beta = 0.0
        elif (A <= 50): beta = 0.5842*(A-21)**0.4 + 0.07886*(A-21)
        else: beta = 0.1102*(A-8.7)
        window=('kaiser',beta)

    win = get_window(window,N,fftbins=1)
    alpha = N//2
    m = numpy.arange(0,N)
    h = win*special.sinc(cutoff*(m-alpha))
    return h / numpy.sum(h,axis=0)
Exemple #6
0
def sinc(X, Y):
    n = len(X)
    m = len(Y)
    res = np.zeros((n, m))
    for i in range(n):
        for j in range(m):
            res[i][j] = sc.sinc(np.linalg.norm(X[i] - Y[j]))
    return res
 def test04(self):
     """Test firwin2 when window=None."""
     ntaps = 5
     # Ideal lowpass: gain is 1 on [0,0.5], and 0 on [0.5, 1.0]
     freq = [0.0, 0.5, 0.5, 1.0]
     gain = [1.0, 1.0, 0.0, 0.0]
     taps = firwin2(ntaps, freq, gain, window=None, nfreqs=8193)
     alpha = 0.5 * (ntaps - 1)
     m = np.arange(0, ntaps) - alpha
     h = 0.5 * sinc(0.5 * m)
     assert_array_almost_equal(h, taps)
 def test04(self):
     """Test firwin2 when window=None."""
     ntaps = 5
     # Ideal lowpass: gain is 1 on [0,0.5], and 0 on [0.5, 1.0]
     freq = [0.0, 0.5, 0.5, 1.0]
     gain = [1.0, 1.0, 0.0, 0.0]
     taps = firwin2(ntaps, freq, gain, window=None, nfreqs=8193)
     alpha = 0.5 * (ntaps - 1)
     m = np.arange(0, ntaps) - alpha
     h = 0.5 * sinc(0.5 * m)
     assert_array_almost_equal(h, taps)
Exemple #9
0
def firls(N, f, D=None):
    """Least-squares FIR filter.
    N -- filter length, must be odd
    f -- list of tuples of band edges
       Units of band edges are Hz with 0.5 Hz == Nyquist
       and assumed 1 Hz sampling frequency
    D -- list of desired responses, one per band
    """
    if D is None:
        D = [1, 0]
    assert len(D) == len(f), "must have one desired response per band"
    assert N%2 == 1, 'filter length must be odd'
    L = (N-1)//2

    k = np.arange(L+1)
    k.shape = (1, L+1)
    j = k.T

    R = 0
    r = 0
    for i, (f0, f1) in enumerate(f):
        R += np.pi*f1*sinc(2*(j-k)*f1) - np.pi*f0*sinc(2*(j-k)*f0) + \
             np.pi*f1*sinc(2*(j+k)*f1) - np.pi*f0*sinc(2*(j+k)*f0)

        r += D[i]*(2*np.pi*f1*sinc(2*j*f1) - 2*np.pi*f0*sinc(2*j*f0))

    a = np.dot(np.linalg.inv(R), r)
    a.shape = (-1,)
    h = np.zeros(N)
    h[:L] = a[:0:-1]/2.
    h[L] = a[0]
    h[L+1:] = a[1:]/2.
    return h
Exemple #10
0
def slepian(M, width, sym=True):
    """Return a digital Slepian window.

    Used to maximize the energy concentration in the main lobe.  Also called
    the digital prolate spheroidal sequence (DPSS).

    Parameters
    ----------
    M : int
        Number of points in the output window. If zero or less, an empty
        array is returned.
    width : float
        Bandwidth
    sym : bool, optional
        When True, generates a symmetric window, for use in filter design.
        When False, generates a periodic window, for use in spectral analysis.

    Returns
    -------
    w : ndarray
        The window, with the maximum value always normalized to 1

    """
    if (M * width > 27.38):
        raise ValueError("Cannot reliably obtain slepian sequences for"
              " M*width > 27.38.")
    if M < 1:
        return np.array([])
    if M == 1:
        return np.ones(1, 'd')
    odd = M % 2
    if not sym and not odd:
        M = M + 1

    twoF = width / 2.0
    alpha = (M - 1) / 2.0
    m = np.arange(0, M) - alpha
    n = m[:, np.newaxis]
    k = m[np.newaxis, :]
    AF = twoF * special.sinc(twoF * (n - k))
    [lam, vec] = linalg.eig(AF)
    ind = np.argmax(abs(lam), axis=-1)
    w = np.abs(vec[:, ind])
    w = w / max(w)

    if not sym and not odd:
        w = w[:-1]
    return w
Exemple #11
0
def slepian(M, width, sym=True):
    """Return a digital Slepian window.

    Used to maximize the energy concentration in the main lobe.  Also called
    the digital prolate spheroidal sequence (DPSS).

    Parameters
    ----------
    M : int
        Number of points in the output window. If zero or less, an empty
        array is returned.
    width : float
        Bandwidth
    sym : bool, optional
        When True, generates a symmetric window, for use in filter design.
        When False, generates a periodic window, for use in spectral analysis.

    Returns
    -------
    w : ndarray
        The window, with the maximum value always normalized to 1

    """
    if (M * width > 27.38):
        raise ValueError("Cannot reliably obtain slepian sequences for"
                         " M*width > 27.38.")
    if M < 1:
        return np.array([])
    if M == 1:
        return np.ones(1, 'd')
    odd = M % 2
    if not sym and not odd:
        M = M + 1

    twoF = width / 2.0
    alpha = (M - 1) / 2.0
    m = np.arange(0, M) - alpha
    n = m[:, np.newaxis]
    k = m[np.newaxis, :]
    AF = twoF * special.sinc(twoF * (n - k))
    [lam, vec] = linalg.eig(AF)
    ind = np.argmax(abs(lam), axis=-1)
    w = np.abs(vec[:, ind])
    w = w / max(w)

    if not sym and not odd:
        w = w[:-1]
    return w
Exemple #12
0
def zeta_squared_error(x1, x2, b):
    sum = 0
    l = 1
    c1 = -2. * numpy.pi / math.log(b)
    f = cmath.exp(complex(0, numpy.pi * (x1 + x2)))
    fn = f
    while True:
        oldsum = sum
        g = gamma_cache.get((c1, l))
        if g is None:
            g = gamma(complex(1, c1 * l))
            gamma_cache[(c1, l)] = g
        sum += g * fn * sinc(l * (x1 - x2))
        if oldsum == sum:
            break
        l += 1
        fn *= f
    return pow(sum.real, 2)
Exemple #13
0
def run():

    n = np.arange(-20, 21, 1)
    x = 0.5 * (sinc(n / 2))**2
    print("x", x.shape)
    fig1 = plt.figure(1, figsize=(15, 8), dpi=98)
    fig1.add_subplot(211)
    plt.subplot(211, xlabel="n", ylabel="y")
    plt.grid("-.")
    plt.plot(n, x)
    plt.ylim(0, 0.6)

    plt.subplot(212, xlabel="n", ylabel="y")
    plt.stem(n, x)
    plt.ylim(0, 0.6)

    ts = 1 / 40
    fig2 = plt.figure(2, figsize=(15, 8), dpi=98)
    fig2.add_subplot(111)
    plt.subplot(111)
    t = np.arange(-0.5, 1.5, ts)
    print("t", t.shape)
    fs = 1 / ts
    b = np.hstack((np.zeros((1, 20))[0], t[20:60], np.zeros((1, 20))[0]))
    print("b", b.shape)
    H = fft(b) / fs
    print("H", H.shape)
    df = fs / 80
    f = np.arange(0, fs, df) - fs / 2
    print("f", f.shape)
    plt.plot(b, f)
    H1 = fftshift(H)
    print("H1", H1.shape)
    y = x * H1[19:60]

    fig3 = plt.figure(3, figsize=(15, 8), dpi=98)
    fig3.add_subplot(111)
    plt.subplot(111)
    plt.stem(n, y, linefmt='r-', basefmt='r-', markerfmt='C3.')
    plt.ylim(-0.2, 0.3)
    fig1.savefig("./1.png")
    fig2.savefig("./2.png")
    fig3.savefig("./3.png")
    plt.show()
    def convert(self, signal: Signal, step: int) -> Signal:
        old_sampling_period = (signal.samples[-1] - signal.samples[0]) / len(
            signal.samples)
        new_sampling_period = (signal.samples[-1] -
                               signal.samples[0]) / self._sampling_rate.rate

        new_samples = []
        new_x_values = self.get_signal_x_values(signal, new_sampling_period)
        for new_x in new_x_values:
            new_value = 0
            old_x_values = self.get_arguments(signal)
            for old_index in range(len(old_x_values)):
                new_value += signal.samples[old_index] * sinc(
                    new_x / old_sampling_period - old_index)
            new_samples.append(new_value)

        new_signal = deepcopy(signal)
        new_signal.samples = new_samples
        new_signal.sampling_frequency = self._sampling_rate.rate
        return new_signal
Exemple #15
0
def digit_baseband():

    Ts = 1
    N_sample = 8  # 每个码元的抽样点数
    dt = Ts / N_sample  # 抽样时间间隔
    N = 1000  # 码元数
    T = 1
    t = np.arange(0, N * N_sample * dt, dt)

    gt1 = np.ones((1, N_sample))  # NRZ非归零波形

    gt2 = np.ones((1, N_sample // 2))  # RZ归零波形

    gt2 = np.hstack((gt2, np.zeros((1, N_sample // 2))))

    mt3 = sinc((t - 5) / Ts).reshape(1,
                                     -1)  #  sin(pi * t / Ts) / (pi * t / Ts)

    gt3 = mt3[0:10 * N_sample].reshape((1, -1))

    d = (np.sign(np.random.randn(1, N)) + 1) / 2

    data = sigexpand(d, N_sample)  # 对序列间隔插入N_sample - 1个0

    st1 = convolve(data, gt1)

    st2 = convolve(data, gt2)

    d = 2 * d - 1  #变成双极性序列

    data = sigexpand(d, N_sample)

    st3 = convolve(data, gt3)

    f1, st1f = T2F(t, st1[:len(t)])

    f2, st2f = T2F(t, st2[:len(t)])

    f3, st3f = T2F(t, st3[:len(t)])

    fig1 = plt.figure(1, figsize=(13, 8), dpi=98)
    fig1.add_subplot(321)
    plt.subplot(3, 2, 1, ylabel='单极性NRZ波形')
    plt.xlim(0, 20)  # axis([0 20 - 1.5 1.5]);
    plt.ylim(-2, 2)  # axis([0 20 - 1.5 1.5]);
    plt.grid("-.")

    plt.plot(t, st1[0][:len(t)])

    fig1.add_subplot(322)
    plt.grid("-.")
    plt.xlim(-5, 5)  # axis([0 20 - 1.5 1.5]);
    plt.ylim(-40, 10)
    plt.plot(f1, 10 * np.log10(abs(st1f)**2 / T))

    fig1.add_subplot(323, ylabel='单极性RZ波形')
    plt.grid("-.")
    plt.xlim(0, 20)
    plt.ylim(-1.5, 1.5)
    plt.plot(t, st2[0][:len(t)])

    fig1.add_subplot(324, ylabel='单极性RZ功率谱密度(dB/Hz)')
    plt.grid("-.")
    plt.xlim(-5, 5)
    plt.ylim(-40, 10)
    plt.plot(f2, 10 * np.log10(abs(st2f)**2 / T))

    fig1.add_subplot(325, ylabel='双极性sinc波形', xlabel='t/Ts')

    plt.plot(t - 5, st3[0][:len(t)])
    plt.grid("-.")
    plt.xlim(0, 20)
    plt.ylim(-2, 2)

    fig1.add_subplot(326, ylabel='sinc波形功率谱密度(dB/Hz)', xlabel='f*Ts')
    plt.grid("-.")
    plt.xlim(-5, 5)
    plt.ylim(-40, 10)
    plt.plot(f3[:-1], 10 * np.log10(abs(st3f)**2 / T))
    plt.show()
Exemple #16
0
def findfreqs(num, den, N):
    m = numpy.arange(0, N)
    h = win * special.sinc(cutoff * (m - alpha))
    return h / numpy.sum(h, axis=0)
Exemple #17
0
    def firwin(self,
               numtaps,
               cutoff,
               window=None,
               pass_zero=True,
               scale=True,
               nyq=1.0,
               fs=None):
        """
        FIR filter design using the window method. This is more or less the 
        same as `scipy.signal.firwin` with the exception that an ndarray with 
        the window values can be passed as an alternative to the window name.
        
        The parameters "width" (specifying a Kaiser window) and "fs" have been
        omitted, they are not needed here.

        This function computes the coefficients of a finite impulse response
        filter.  The filter will have linear phase; it will be Type I if
        `numtaps` is odd and Type II if `numtaps` is even.
        Type II filters always have zero response at the Nyquist rate, so a
        ValueError exception is raised if firwin is called with `numtaps` even and
        having a passband whose right end is at the Nyquist rate.
        
        Parameters
        ----------
        numtaps : int
            Length of the filter (number of coefficients, i.e. the filter
            order + 1).  `numtaps` must be even if a passband includes the
            Nyquist frequency.
        cutoff : float or 1D array_like
            Cutoff frequency of filter (expressed in the same units as `nyq`)
            OR an array of cutoff frequencies (that is, band edges). In the
            latter case, the frequencies in `cutoff` should be positive and
            monotonically increasing between 0 and `nyq`.  The values 0 and
            `nyq` must not be included in `cutoff`.
        window : ndarray or string
            string: use the window with the passed name from scipy.signal.windows
            
            ndarray: The window values - this is an addition to the original 
            firwin routine.
        pass_zero : bool, optional
            If True, the gain at the frequency 0 (i.e. the "DC gain") is 1.
            Otherwise the DC gain is 0.
        scale : bool, optional
            Set to True to scale the coefficients so that the frequency
            response is exactly unity at a certain frequency.
            That frequency is either:
            - 0 (DC) if the first passband starts at 0 (i.e. pass_zero
              is True)
            - `nyq` (the Nyquist rate) if the first passband ends at
              `nyq` (i.e the filter is a single band highpass filter);
              center of first passband otherwise
        nyq : float, optional
            Nyquist frequency.  Each frequency in `cutoff` must be between 0
            and `nyq`.
        Returns
        -------
        h : (numtaps,) ndarray
            Coefficients of length `numtaps` FIR filter.
        Raises
        ------
        ValueError
            If any value in `cutoff` is less than or equal to 0 or greater
            than or equal to `nyq`, if the values in `cutoff` are not strictly
            monotonically increasing, or if `numtaps` is even but a passband
            includes the Nyquist frequency.
        See also
        --------
        scipy.firwin
        """
        cutoff = np.atleast_1d(cutoff) / float(nyq)

        # Check for invalid input.
        if cutoff.ndim > 1:
            raise ValueError("The cutoff argument must be at most "
                             "one-dimensional.")
        if cutoff.size == 0:
            raise ValueError("At least one cutoff frequency must be given.")
        if cutoff.min() <= 0 or cutoff.max() >= 1:
            raise ValueError(
                "Invalid cutoff frequency {0}: frequencies must be "
                "greater than 0 and less than nyq.".format(cutoff))
        if np.any(np.diff(cutoff) <= 0):
            raise ValueError("Invalid cutoff frequencies: the frequencies "
                             "must be strictly increasing.")

        pass_nyquist = bool(cutoff.size & 1) ^ pass_zero
        if pass_nyquist and numtaps % 2 == 0:
            raise ValueError(
                "A filter with an even number of coefficients must "
                "have zero response at the Nyquist rate.")

        # Insert 0 and/or 1 at the ends of cutoff so that the length of cutoff
        # is even, and each pair in cutoff corresponds to passband.
        cutoff = np.hstack(([0.0] * pass_zero, cutoff, [1.0] * pass_nyquist))

        # `bands` is a 2D array; each row gives the left and right edges of
        # a passband.
        bands = cutoff.reshape(-1, 2)

        # Build up the coefficients.
        alpha = 0.5 * (numtaps - 1)
        m = np.arange(0, numtaps) - alpha
        h = 0
        for left, right in bands:
            h += right * sinc(right * m)
            h -= left * sinc(left * m)

        if type(window) == str:
            # Get and apply the window function.
            from scipy.signal.signaltools import get_window
            win = get_window(window, numtaps, fftbins=False)
        elif type(window) == np.ndarray:
            win = window
        else:
            logger.error(
                "The 'window' was neither a string nor a numpy array, it could not be evaluated."
            )
            return None
        # apply the window function.
        h *= win

        # Now handle scaling if desired.
        if scale:
            # Get the first passband.
            left, right = bands[0]
            if left == 0:
                scale_frequency = 0.0
            elif right == 1:
                scale_frequency = 1.0
            else:
                scale_frequency = 0.5 * (left + right)
            c = np.cos(np.pi * m * scale_frequency)
            s = np.sum(h * c)
            h /= s

        return h
 def __init__(self, a):
     """
     a : bandwidth
     """
     super(Sinc, self).__init__(domain=(-np.inf, np.inf))
     self.timeFunc = lambda t: sinc(a*t)
Exemple #19
0
def findfreqs(num, den, N):
    m = np.arange(0,N)
    h = win*special.sinc(cutoff*(m-alpha))
    return h / np.sum(h,axis=0)
def firwin(numtaps, cutoff, width=None, window='hamming', pass_zero=True,
                                                        scale=True, nyq=1.0):
    """
    FIR filter design using the window method.
    
    This function computes the coefficients of a finite impulse response filter.
    The filter will have linear phase; it will be Type I if `numtaps` is odd and
    Type II if `numtaps` is even.
    
    Type II filters always have zero response at the Nyquist rate, so a
    ValueError exception is raised if firwin is called with `numtaps` even and
    having a passband whose right end is at the Nyquist rate.

    Parameters
    ----------
    numtaps : int
        Length of the filter (number of coefficients, i.e. the filter
        order + 1).  `numtaps` must be even if a passband includes the
        Nyquist frequency.

    cutoff : float or 1D array_like
        Cutoff frequency of filter (expressed in the same units as `nyq`)
        OR an array of cutoff frequencies (that is, band edges). In the
        latter case, the frequencies in `cutoff` should be positive and
        monotonically increasing between 0 and `nyq`.  The values 0 and
        `nyq` must not be included in `cutoff`.

    width : float or None
        If `width` is not None, then assume it is the approximate width
        of the transition region (expressed in the same units as `nyq`)
        for use in Kaiser FIR filter design.  In this case, the `window`
        argument is ignored.

    window : string or tuple of string and parameter values
        Desired window to use. See `scipy.signal.get_window` for a list
        of windows and required parameters.

    pass_zero : bool
        If True, the gain at the frequency 0 (i.e. the "DC gain") is 1.
        Otherwise the DC gain is 0.

    scale : bool
        Set to True to scale the coefficients so that the frequency
        response is exactly unity at a certain frequency.
        That frequency is either:
            0 (DC) if the first passband starts at 0 (i.e. pass_zero
                is True);
            `nyq` (the Nyquist rate) if the first passband ends at
                `nyq` (i.e the filter is a single band highpass filter);
            center of first passband otherwise.

    nyq : float
        Nyquist frequency.  Each frequency in `cutoff` must be between 0
        and `nyq`.

    Returns
    -------
    h : 1D ndarray
        Coefficients of length `numtaps` FIR filter.

    Raises
    ------
    ValueError
        If any value in `cutoff` is less than or equal to 0 or greater
        than or equal to `nyq`, if the values in `cutoff` are not strictly
        monotonically increasing, or if `numtaps` is even but a passband
        includes the Nyquist frequency.

    Examples
    --------
    
    Low-pass from 0 to f::
    
    >>> firwin(numtaps, f)
    
    Use a specific window function::
    
    >>> firwin(numtaps, f, window='nuttall')
    
    High-pass ('stop' from 0 to f)::
     
    >>> firwin(numtaps, f, pass_zero=False)

    Band-pass::
    
    >>> firwin(numtaps, [f1, f2], pass_zero=False)
    
    Band-stop::
    
    >>> firwin(numtaps, [f1, f2]) 

    Multi-band (passbands are [0, f1], [f2, f3] and [f4, 1])::

    >>>firwin(numtaps, [f1, f2, f3, f4])
    
    Multi-band (passbands are [f1, f2] and [f3,f4])::
    
    >>> firwin(numtaps, [f1, f2, f3, f4], pass_zero=False)

    See also
    --------
    scipy.signal.firwin2

    """

    # The major enhancements to this function added in November 2010 were
    # developed by Tom Krauss (see ticket #902).

    cutoff = np.atleast_1d(cutoff) / float(nyq)

    # Check for invalid input.
    if cutoff.ndim > 1:
        raise ValueError("The cutoff argument must be at most one-dimensional.")
    if cutoff.size == 0:
        raise ValueError("At least one cutoff frequency must be given.")
    if cutoff.min() <= 0 or cutoff.max() >= 1:
        raise ValueError("Invalid cutoff frequency: frequencies must be greater than 0 and less than nyq.")
    if np.any(np.diff(cutoff) <= 0):
        raise ValueError("Invalid cutoff frequencies: the frequencies must be strictly increasing.")

    if width is not None:
        # A width was given.  Find the beta parameter of the Kaiser window
        # and set `window`.  This overrides the value of `window` passed in.
        atten = kaiser_atten(numtaps, float(width)/nyq)
        beta = kaiser_beta(atten)
        window = ('kaiser', beta)

    pass_nyquist = bool(cutoff.size & 1) ^ pass_zero
    if pass_nyquist and numtaps % 2 == 0:
        raise ValueError("A filter with an even number of coefficients must "
                            "have zero response at the Nyquist rate.")

    # Insert 0 and/or 1 at the ends of cutoff so that the length of cutoff is even,
    # and each pair in cutoff corresponds to passband.
    cutoff = np.hstack(([0.0]*pass_zero, cutoff, [1.0]*pass_nyquist))

    # `bands` is a 2D array; each row gives the left and right edges of a passband.
    bands = cutoff.reshape(-1,2)

    # Build up the coefficients.
    alpha = 0.5 * (numtaps-1)
    m = np.arange(0, numtaps) - alpha
    h = 0
    for left, right in bands:
        h += right * sinc(right * m)
        h -= left * sinc(left * m)

    # Get and apply the window function.
    from signaltools import get_window
    win = get_window(window, numtaps, fftbins=False)
    h *= win
        
    # Now handle scaling if desired.
    if scale:
        # Get the first passband.
        left, right = bands[0]
        if left == 0:
            scale_frequency = 0.0
        elif right == 1:
            scale_frequency = 1.0
        else:
            scale_frequency = 0.5 * (left + right)
        c = np.cos(np.pi * m * scale_frequency)
        s = np.sum(h * c)
        h /= s
 
    return h
def firwin(numtaps, cutoff, width=None, window='hamming', pass_zero=True,
           scale=True, nyq=None, fs=None):
    """
    FIR filter design using the window method.

    This function computes the coefficients of a finite impulse response
    filter.  The filter will have linear phase; it will be Type I if
    `numtaps` is odd and Type II if `numtaps` is even.

    Type II filters always have zero response at the Nyquist frequency, so a
    ValueError exception is raised if firwin is called with `numtaps` even and
    having a passband whose right end is at the Nyquist frequency.

    Parameters
    ----------
    numtaps : int
        Length of the filter (number of coefficients, i.e. the filter
        order + 1).  `numtaps` must be odd if a passband includes the
        Nyquist frequency.
    cutoff : float or 1D array_like
        Cutoff frequency of filter (expressed in the same units as `fs`)
        OR an array of cutoff frequencies (that is, band edges). In the
        latter case, the frequencies in `cutoff` should be positive and
        monotonically increasing between 0 and `fs/2`.  The values 0 and
        `fs/2` must not be included in `cutoff`.
    width : float or None, optional
        If `width` is not None, then assume it is the approximate width
        of the transition region (expressed in the same units as `fs`)
        for use in Kaiser FIR filter design.  In this case, the `window`
        argument is ignored.
    window : string or tuple of string and parameter values, optional
        Desired window to use. See `scipy.signal.get_window` for a list
        of windows and required parameters.
    pass_zero : {True, False, 'bandpass', 'lowpass', 'highpass', 'bandstop'}, optional
        If True, the gain at the frequency 0 (i.e. the "DC gain") is 1.
        If False, the DC gain is 0. Can also be a string argument for the
        desired filter type (equivalent to ``btype`` in IIR design functions).

        .. versionadded:: 1.3.0
           Support for string arguments.
    scale : bool, optional
        Set to True to scale the coefficients so that the frequency
        response is exactly unity at a certain frequency.
        That frequency is either:

        - 0 (DC) if the first passband starts at 0 (i.e. pass_zero
          is True)
        - `fs/2` (the Nyquist frequency) if the first passband ends at
          `fs/2` (i.e the filter is a single band highpass filter);
          center of first passband otherwise

    nyq : float, optional
        *Deprecated.  Use `fs` instead.*  This is the Nyquist frequency.
        Each frequency in `cutoff` must be between 0 and `nyq`. Default
        is 1.
    fs : float, optional
        The sampling frequency of the signal.  Each frequency in `cutoff`
        must be between 0 and ``fs/2``.  Default is 2.

    Returns
    -------
    h : (numtaps,) ndarray
        Coefficients of length `numtaps` FIR filter.

    Raises
    ------
    ValueError
        If any value in `cutoff` is less than or equal to 0 or greater
        than or equal to ``fs/2``, if the values in `cutoff` are not strictly
        monotonically increasing, or if `numtaps` is even but a passband
        includes the Nyquist frequency.

    See Also
    --------
    firwin2
    firls
    minimum_phase
    remez

    Examples
    --------
    Low-pass from 0 to f:

    >>> from scipy import signal
    >>> numtaps = 3
    >>> f = 0.1
    >>> signal.firwin(numtaps, f)
    array([ 0.06799017,  0.86401967,  0.06799017])

    Use a specific window function:

    >>> signal.firwin(numtaps, f, window='nuttall')
    array([  3.56607041e-04,   9.99286786e-01,   3.56607041e-04])

    High-pass ('stop' from 0 to f):

    >>> signal.firwin(numtaps, f, pass_zero=False)
    array([-0.00859313,  0.98281375, -0.00859313])

    Band-pass:

    >>> f1, f2 = 0.1, 0.2
    >>> signal.firwin(numtaps, [f1, f2], pass_zero=False)
    array([ 0.06301614,  0.88770441,  0.06301614])

    Band-stop:

    >>> signal.firwin(numtaps, [f1, f2])
    array([-0.00801395,  1.0160279 , -0.00801395])

    Multi-band (passbands are [0, f1], [f2, f3] and [f4, 1]):

    >>> f3, f4 = 0.3, 0.4
    >>> signal.firwin(numtaps, [f1, f2, f3, f4])
    array([-0.01376344,  1.02752689, -0.01376344])

    Multi-band (passbands are [f1, f2] and [f3,f4]):

    >>> signal.firwin(numtaps, [f1, f2, f3, f4], pass_zero=False)
    array([ 0.04890915,  0.91284326,  0.04890915])

    """  # noqa: E501
    # The major enhancements to this function added in November 2010 were
    # developed by Tom Krauss (see ticket #902).

    nyq = 0.5 * _get_fs(fs, nyq)

    cutoff = np.atleast_1d(cutoff) / float(nyq)

    # Check for invalid input.
    if cutoff.ndim > 1:
        raise ValueError("The cutoff argument must be at most "
                         "one-dimensional.")
    if cutoff.size == 0:
        raise ValueError("At least one cutoff frequency must be given.")
    if cutoff.min() <= 0 or cutoff.max() >= 1:
        raise ValueError("Invalid cutoff frequency: frequencies must be "
                         "greater than 0 and less than fs/2.")
    if np.any(np.diff(cutoff) <= 0):
        raise ValueError("Invalid cutoff frequencies: the frequencies "
                         "must be strictly increasing.")

    if width is not None:
        # A width was given.  Find the beta parameter of the Kaiser window
        # and set `window`.  This overrides the value of `window` passed in.
        atten = kaiser_atten(numtaps, float(width) / nyq)
        beta = kaiser_beta(atten)
        window = ('kaiser', beta)

    if isinstance(pass_zero, str):
        if pass_zero in ('bandstop', 'lowpass'):
            if pass_zero == 'lowpass':
                if cutoff.size != 1:
                    raise ValueError('cutoff must have one element if '
                                     'pass_zero=="lowpass", got %s'
                                     % (cutoff.shape,))
            elif cutoff.size <= 1:
                raise ValueError('cutoff must have at least two elements if '
                                 'pass_zero=="bandstop", got %s'
                                 % (cutoff.shape,))
            pass_zero = True
        elif pass_zero in ('bandpass', 'highpass'):
            if pass_zero == 'highpass':
                if cutoff.size != 1:
                    raise ValueError('cutoff must have one element if '
                                     'pass_zero=="highpass", got %s'
                                     % (cutoff.shape,))
            elif cutoff.size <= 1:
                raise ValueError('cutoff must have at least two elements if '
                                 'pass_zero=="bandpass", got %s'
                                 % (cutoff.shape,))
            pass_zero = False
        else:
            raise ValueError('pass_zero must be True, False, "bandpass", '
                             '"lowpass", "highpass", or "bandstop", got '
                             '%s' % (pass_zero,))
    pass_zero = bool(operator.index(pass_zero))  # ensure bool-like

    pass_nyquist = bool(cutoff.size & 1) ^ pass_zero
    if pass_nyquist and numtaps % 2 == 0:
        raise ValueError("A filter with an even number of coefficients must "
                         "have zero response at the Nyquist frequency.")

    # Insert 0 and/or 1 at the ends of cutoff so that the length of cutoff
    # is even, and each pair in cutoff corresponds to passband.
    cutoff = np.hstack(([0.0] * pass_zero, cutoff, [1.0] * pass_nyquist))

    # `bands` is a 2D array; each row gives the left and right edges of
    # a passband.
    bands = cutoff.reshape(-1, 2)

    # Build up the coefficients.
    alpha = 0.5 * (numtaps - 1)
    m = np.arange(0, numtaps) - alpha
    h = 0
    for left, right in bands:
        h += right * sinc(right * m)
        h -= left * sinc(left * m)

    # Get and apply the window function.
    from .signaltools import get_window
    win = get_window(window, numtaps, fftbins=False)
    h *= win

    # Now handle scaling if desired.
    if scale:
        # Get the first passband.
        left, right = bands[0]
        if left == 0:
            scale_frequency = 0.0
        elif right == 1:
            scale_frequency = 1.0
        else:
            scale_frequency = 0.5 * (left + right)
        c = np.cos(np.pi * m * scale_frequency)
        s = np.sum(h * c)
        h /= s

    return h
Exemple #22
0
import numpy as np
from scipy import special
import matplotlib.pylab as plt

domain = np.linspace(0, 2 *np.pi, 512)

sinc_write = special.sinc(domain)

plt.plot(domain, sinc_write)

plt.show()
Exemple #23
0
def firwin(numtaps, cutoff, width=None, window='hamming', pass_zero=True,
           scale=True, nyq=None, fs=None):
    """
    FIR filter design using the window method.

    This function computes the coefficients of a finite impulse response
    filter. The filter will have linear phase; it will be Type I if
    `numtaps` is odd and Type II if `numtaps` is even.

    Type II filters always have zero response at the Nyquist frequency, so a
    ValueError exception is raised if firwin is called with `numtaps` even and
    having a passband whose right end is at the Nyquist frequency.

    Parameters
    ----------
    numtaps : int
        Length of the filter (number of coefficients, i.e. the filter
        order + 1).  `numtaps` must be odd if a passband includes the
        Nyquist frequency.
    cutoff : float or 1-D array_like
        Cutoff frequency of filter (expressed in the same units as `fs`)
        OR an array of cutoff frequencies (that is, band edges). In the
        latter case, the frequencies in `cutoff` should be positive and
        monotonically increasing between 0 and `fs/2`. The values 0 and
        `fs/2` must not be included in `cutoff`.
    width : float or None, optional
        If `width` is not None, then assume it is the approximate width
        of the transition region (expressed in the same units as `fs`)
        for use in Kaiser FIR filter design. In this case, the `window`
        argument is ignored.
    window : string or tuple of string and parameter values, optional
        Desired window to use. See `scipy.signal.get_window` for a list
        of windows and required parameters.
    pass_zero : {True, False, 'bandpass', 'lowpass', 'highpass', 'bandstop'}, optional
        If True, the gain at the frequency 0 (i.e., the "DC gain") is 1.
        If False, the DC gain is 0. Can also be a string argument for the
        desired filter type (equivalent to ``btype`` in IIR design functions).

        .. versionadded:: 1.3.0
           Support for string arguments.
    scale : bool, optional
        Set to True to scale the coefficients so that the frequency
        response is exactly unity at a certain frequency.
        That frequency is either:

        - 0 (DC) if the first passband starts at 0 (i.e. pass_zero
          is True)
        - `fs/2` (the Nyquist frequency) if the first passband ends at
          `fs/2` (i.e the filter is a single band highpass filter);
          center of first passband otherwise

    nyq : float, optional
        *Deprecated. Use `fs` instead.* This is the Nyquist frequency.
        Each frequency in `cutoff` must be between 0 and `nyq`. Default
        is 1.
    fs : float, optional
        The sampling frequency of the signal. Each frequency in `cutoff`
        must be between 0 and ``fs/2``.  Default is 2.

    Returns
    -------
    h : (numtaps,) ndarray
        Coefficients of length `numtaps` FIR filter.

    Raises
    ------
    ValueError
        If any value in `cutoff` is less than or equal to 0 or greater
        than or equal to ``fs/2``, if the values in `cutoff` are not strictly
        monotonically increasing, or if `numtaps` is even but a passband
        includes the Nyquist frequency.

    See Also
    --------
    firwin2
    firls
    minimum_phase
    remez

    Examples
    --------
    Low-pass from 0 to f:

    >>> from scipy import signal
    >>> numtaps = 3
    >>> f = 0.1
    >>> signal.firwin(numtaps, f)
    array([ 0.06799017,  0.86401967,  0.06799017])

    Use a specific window function:

    >>> signal.firwin(numtaps, f, window='nuttall')
    array([  3.56607041e-04,   9.99286786e-01,   3.56607041e-04])

    High-pass ('stop' from 0 to f):

    >>> signal.firwin(numtaps, f, pass_zero=False)
    array([-0.00859313,  0.98281375, -0.00859313])

    Band-pass:

    >>> f1, f2 = 0.1, 0.2
    >>> signal.firwin(numtaps, [f1, f2], pass_zero=False)
    array([ 0.06301614,  0.88770441,  0.06301614])

    Band-stop:

    >>> signal.firwin(numtaps, [f1, f2])
    array([-0.00801395,  1.0160279 , -0.00801395])

    Multi-band (passbands are [0, f1], [f2, f3] and [f4, 1]):

    >>> f3, f4 = 0.3, 0.4
    >>> signal.firwin(numtaps, [f1, f2, f3, f4])
    array([-0.01376344,  1.02752689, -0.01376344])

    Multi-band (passbands are [f1, f2] and [f3,f4]):

    >>> signal.firwin(numtaps, [f1, f2, f3, f4], pass_zero=False)
    array([ 0.04890915,  0.91284326,  0.04890915])

    """  # noqa: E501
    # The major enhancements to this function added in November 2010 were
    # developed by Tom Krauss (see ticket #902).

    nyq = 0.5 * _get_fs(fs, nyq)

    cutoff = np.atleast_1d(cutoff) / float(nyq)

    # Check for invalid input.
    if cutoff.ndim > 1:
        raise ValueError("The cutoff argument must be at most "
                         "one-dimensional.")
    if cutoff.size == 0:
        raise ValueError("At least one cutoff frequency must be given.")
    if cutoff.min() <= 0 or cutoff.max() >= 1:
        raise ValueError("Invalid cutoff frequency: frequencies must be "
                         "greater than 0 and less than fs/2.")
    if np.any(np.diff(cutoff) <= 0):
        raise ValueError("Invalid cutoff frequencies: the frequencies "
                         "must be strictly increasing.")

    if width is not None:
        # A width was given.  Find the beta parameter of the Kaiser window
        # and set `window`.  This overrides the value of `window` passed in.
        atten = kaiser_atten(numtaps, float(width) / nyq)
        beta = kaiser_beta(atten)
        window = ('kaiser', beta)

    if isinstance(pass_zero, str):
        if pass_zero in ('bandstop', 'lowpass'):
            if pass_zero == 'lowpass':
                if cutoff.size != 1:
                    raise ValueError('cutoff must have one element if '
                                     'pass_zero=="lowpass", got %s'
                                     % (cutoff.shape,))
            elif cutoff.size <= 1:
                raise ValueError('cutoff must have at least two elements if '
                                 'pass_zero=="bandstop", got %s'
                                 % (cutoff.shape,))
            pass_zero = True
        elif pass_zero in ('bandpass', 'highpass'):
            if pass_zero == 'highpass':
                if cutoff.size != 1:
                    raise ValueError('cutoff must have one element if '
                                     'pass_zero=="highpass", got %s'
                                     % (cutoff.shape,))
            elif cutoff.size <= 1:
                raise ValueError('cutoff must have at least two elements if '
                                 'pass_zero=="bandpass", got %s'
                                 % (cutoff.shape,))
            pass_zero = False
        else:
            raise ValueError('pass_zero must be True, False, "bandpass", '
                             '"lowpass", "highpass", or "bandstop", got '
                             '%s' % (pass_zero,))
    pass_zero = bool(operator.index(pass_zero))  # ensure bool-like

    pass_nyquist = bool(cutoff.size & 1) ^ pass_zero
    if pass_nyquist and numtaps % 2 == 0:
        raise ValueError("A filter with an even number of coefficients must "
                         "have zero response at the Nyquist frequency.")

    # Insert 0 and/or 1 at the ends of cutoff so that the length of cutoff
    # is even, and each pair in cutoff corresponds to passband.
    cutoff = np.hstack(([0.0] * pass_zero, cutoff, [1.0] * pass_nyquist))

    # `bands` is a 2-D array; each row gives the left and right edges of
    # a passband.
    bands = cutoff.reshape(-1, 2)

    # Build up the coefficients.
    alpha = 0.5 * (numtaps - 1)
    m = np.arange(0, numtaps) - alpha
    h = 0
    for left, right in bands:
        h += right * sinc(right * m)
        h -= left * sinc(left * m)

    # Get and apply the window function.
    from .signaltools import get_window
    win = get_window(window, numtaps, fftbins=False)
    h *= win

    # Now handle scaling if desired.
    if scale:
        # Get the first passband.
        left, right = bands[0]
        if left == 0:
            scale_frequency = 0.0
        elif right == 1:
            scale_frequency = 1.0
        else:
            scale_frequency = 0.5 * (left + right)
        c = np.cos(np.pi * m * scale_frequency)
        s = np.sum(h * c)
        h /= s

    return h
Exemple #24
0
    def calc_stimulus_frame(self, N_first: int = 0, N_frame: int = 10, N_end: int = 10,
                            init: bool = False) -> np.ndarray:
        """
        Calculate a data frame of stimulus `x` with a length of `N_frame` samples,
        starting with index `N_first`

        Parameters
        ----------
        N_first: int
            index of first data point

        N_frame: int
            number of samples to be generated

        init: bool
            when init == True, initialize stimulus settings

        Returns
        -------
        x: ndarray
            an array with `N` stimulus data points
        """
        if init or N_first == 0:
            '''intialize title string, y-axis label and some variables'''
            # use radians for angle internally
            self.rad_phi1 = self.ui.phi1 / 180 * pi
            self.rad_phi2 = self.ui.phi2 / 180 * pi
            # check whether some amplitude is complex and set array type for xf
            # correspondingly. 
            if (self.ui.ledDC.isVisible and type(self.ui.DC) == complex) or\
                (self.ui.ledAmp1.isVisible and type(self.ui.A1) == complex) or\
                    (self.ui.ledAmp2.isVisible and type(self.ui.A2) == complex):
                self.xf = np.zeros(N_frame, dtype=complex)
            else:
                self.xf = np.zeros(N_frame, dtype=float)

            self.H_str = r'$y[n]$'  # default
            self.title_str = ""
            if self.ui.stim == "none":
                self.title_str = r'Zero Input Response'
                self.H_str = r'$h_0[n]$'
            # ------------------------------------------------------------------
            elif self.ui.stim == "dirac":
                self.title_str = r'Impulse Response'
                self.H_str = r'$h[n]$'
            elif self.ui.stim == "sinc":
                self.title_str = r'Sinc Impulse'
            elif self.ui.stim == "gauss":
                self.title_str = r'Gaussian Impulse'
            elif self.ui.stim == "rect":
                self.title_str = r'Rect Impulse'
            # ------------------------------------------------------------------
            elif self.ui.stim == "step":
                if self.ui.chk_step_err.isChecked():
                    self.title_str = r'Settling Error $\epsilon$'
                    self.H_str = r'$h_{\epsilon, \infty} - h_{\epsilon}[n]$'
                else:
                    self.title_str = r'Step Response'
                    self.H_str = r'$h_{\epsilon}[n]$'
            # ------------------------------------------------------------------
            elif self.ui.stim == "cos":
                self.title_str = r'Cosine Stimulus'
            elif self.ui.stim == "sine":
                self.title_str = r'Sinusoidal Stimulus'
            elif self.ui.stim == "exp":
                self.title_str = r'Complex Exponential Stimulus'
            elif self.ui.stim == "diric":
                self.title_str = r'Periodic Sinc Stimulus'
            # ------------------------------------------------------------------
            elif self.ui.stim == "chirp":
                self.title_str = self.ui.chirp_type.capitalize() + ' Chirp Stimulus'
            # ------------------------------------------------------------------
            elif self.ui.stim == "triang":
                if self.ui.but_stim_bl.isChecked():
                    self.title_str = r'Bandlim. Triangular Stimulus'
                else:
                    self.title_str = r'Triangular Stimulus'
            elif self.ui.stim == "saw":
                if self.ui.but_stim_bl.isChecked():
                    self.title_str = r'Bandlim. Sawtooth Stimulus'
                else:
                    self.title_str = r'Sawtooth Stimulus'
            elif self.ui.stim == "square":
                if self.ui.but_stim_bl.isChecked():
                    self.title_str = r'Bandlimited Rect. Stimulus'
                else:
                    self.title_str = r'Rect. Stimulus'
            elif self.ui.stim == "comb":
                self.title_str = r'Bandlim. Comb Stimulus'
            # ------------------------------------------------------------------
            elif self.ui.stim == "am":
                self.title_str = (
                    r'AM Stimulus: $A_1 \sin(2 \pi n f_1 + \varphi_1)'
                    r'\cdot A_2 \sin(2 \pi n f_2 + \varphi_2)$')
            elif self.ui.stim == "pmfm":
                self.title_str = (
                    r'PM / FM Stimulus: $A_1 \sin(2 \pi n f_1'
                    r'+ \varphi_1 + A_2 \sin(2 \pi n f_2 + \varphi_2))$')
            # ------------------------------------------------------------------
            elif self.ui.stim == "formula":
                self.title_str = r'Formula Defined Stimulus'
            # ==================================================================
            if self.ui.noise == "gauss":
                self.title_str += r' + Gaussian Noise'
            elif self.ui.noise == "uniform":
                self.title_str += r' + Uniform Noise'
            elif self.ui.noise == "prbs":
                self.title_str += r' + PRBS Noise'
            elif self.ui.noise == "mls":
                self.title_str += r' + max. length sequence'
            elif self.ui.noise == "brownian":
                self.title_str += r' + Brownian Noise'
            # ==================================================================
            if self.ui.ledDC.isVisible and self.ui.DC != 0:
                self.title_str += r' + DC'
        # ----------------------------------------------------------------------

        N_last = N_first + N_frame
        n = np.arange(N_first, N_last)

        # T_S = fb.fil[0]['T_S']
        self.T1_idx = int(np.round(self.ui.T1))

        # calculate stimuli x[n] ==============================================
        if self.ui.stim == "none":
            self.xf.fill(0)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "dirac":
            self.xf.fill(0)  # = np.zeros(N_frame, dtype=A_type)
            if N_first <= self.T1_idx < N_last:
                self.xf[self.T1_idx - N_first] = self.ui.A1
        # ----------------------------------------------------------------------
        elif self.ui.stim == "sinc":
            self.xf = self.ui.A1 * sinc(2 * (n - self.ui.T1) * self.ui.f1)\
                + self.ui.A2 * sinc(2 * (n - self.ui.T2) * self.ui.f2)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "gauss":
            self.xf = self.ui.A1 * sig.gausspulse(
                    (n - self.ui.T1), fc=self.ui.f1, bw=self.ui.BW1) +\
                self.ui.A2 * sig.gausspulse(
                    (n - self.ui.T2), fc=self.ui.f2, bw=self.ui.BW2)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "rect":
            n_rise = int(self.T1_idx - np.floor(self.ui.TW1/2))
            n_min = max(n_rise, 0)
            n_max = min(n_rise + self.ui.TW1, N_end)
            self.xf = self.ui.A1 * np.where((n >= n_min) & (n < n_max), 1, 0)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "step":
            if self.T1_idx < N_first:   # step before current frame
                self.xf.fill(self.ui.A1)
            if N_first <= self.T1_idx < N_last:  # step in current frame
                self.xf[0:self.T1_idx - N_first].fill(0)
                self.xf[self.T1_idx - N_first:].fill(self.ui.A1)
            elif self.T1_idx >= N_last:  # step after current frame
                self.xf.fill(0)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "cos":
            self.xf =\
                self.ui.A1 * np.cos(2*pi * n * self.ui.f1 + self.rad_phi1) +\
                self.ui.A2 * np.cos(2*pi * n * self.ui.f2 + self.rad_phi2)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "sine":
            self.xf =\
                self.ui.A1 * np.sin(2*pi * n * self.ui.f1 + self.rad_phi1) +\
                self.ui.A2 * np.sin(2*pi * n * self.ui.f2 + self.rad_phi2)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "exp":
            self.xf =\
                self.ui.A1 * np.exp(1j * (2 * pi * n * self.ui.f1 + self.rad_phi1)) +\
                self.ui.A2 * np.exp(1j * (2 * pi * n * self.ui.f2 + self.rad_phi2))
        # ----------------------------------------------------------------------
        elif self.ui.stim == "diric":
            self.xf = self.ui.A1 * diric(
                (4 * pi * (n-self.ui.T1) * self.ui.f1 + self.rad_phi1*2)
                / self.ui.TW1, self.ui.TW1)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "chirp":
            if self.ui.T2 == 0:  # sig.chirp is buggy, T_sim cannot be larger than T_end
                T_end = N_end  # frequency sweep over complete interval
            else:
                T_end = self.ui.T2  # frequency sweep till T2
            self.xf = self.ui.A1 * sig.chirp(
                n, self.ui.f1, T_end, self.ui.f2,
                method=self.ui.chirp_type, phi=self.rad_phi1)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "triang":
            if self.ui.but_stim_bl.isChecked():
                self.xf = self.ui.A1 * triang_bl(2*pi * n * self.ui.f1 + self.rad_phi1)
            else:
                self.xf = self.ui.A1 * sig.sawtooth(
                    2*pi * n * self.ui.f1 + self.rad_phi1, width=0.5)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "saw":
            if self.ui.but_stim_bl.isChecked():
                self.xf = self.ui.A1 * sawtooth_bl(2*pi * n * self.ui.f1 + self.rad_phi1)
            else:
                self.xf = self.ui.A1 * sig.sawtooth(2*pi * n * self.ui.f1 + self.rad_phi1)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "square":
            if self.ui.but_stim_bl.isChecked():
                self.xf = self.ui.A1 * rect_bl(
                    2 * pi * n * self.ui.f1 + self.rad_phi1, duty=self.ui.stim_par1)
            else:
                self.xf = self.ui.A1 * sig.square(
                    2 * pi * n * self.ui.f1 + self.rad_phi1, duty=self.ui.stim_par1)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "comb":
            self.xf = self.ui.A1 * comb_bl(2 * pi * n * self.ui.f1 + self.rad_phi1)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "am":
            self.xf = self.ui.A1 * np.sin(2*pi * n * self.ui.f1 + self.rad_phi1)\
                * self.ui.A2 * np.sin(2*pi * n * self.ui.f2 + self.rad_phi2)
        # ----------------------------------------------------------------------
        elif self.ui.stim == "pmfm":
            self.xf = self.ui.A1 * np.sin(
                2 * pi * n * self.ui.f1 + self.rad_phi1 +
                self.ui.A2 * np.sin(2*pi * n * self.ui.f2 + self.rad_phi2))
        # ----------------------------------------------------------------------
        elif self.ui.stim == "formula":
            param_dict = {"A1": self.ui.A1, "A2": self.ui.A2,
                          "f1": self.ui.f1, "f2": self.ui.f2,
                          "phi1": self.ui.phi1, "phi2": self.ui.phi2,
                          "BW1": self.ui.BW1, "BW2": self.ui.BW2,
                          "f_S": fb.fil[0]['f_S'], "n": n, "j": 1j}

            self.xf = safe_numexpr_eval(self.ui.stim_formula, (N_frame,), param_dict)
        else:
            logger.error('Unknown stimulus format "{0}"'.format(self.ui.stim))
            return None
        # ----------------------------------------------------------------------
        # Add noise to stimulus
        noi = 0
        if self.ui.noise == "none":
            pass
        elif self.ui.noise == "gauss":
            noi = self.ui.noi * np.random.randn(N_frame)
        elif self.ui.noise == "uniform":
            noi = self.ui.noi * (np.random.rand(N_frame)-0.5)
        elif self.ui.noise == "prbs":
            noi = self.ui.noi * 2 * (np.random.randint(0, 2, N_frame)-0.5)
        elif self.ui.noise == "mls":
            # max_len_seq returns `sequence, state`. The state is not stored here,
            # hence, an identical sequence is created every time.
            noi = self.ui.noi * 2 * (sig.max_len_seq(int(np.ceil(np.log2(N_frame))),
                                     length=N_frame, state=None)[0] - 0.5)
        elif self.ui.noise == "brownian":
            # brownian noise
            noi = np.cumsum(self.ui.noi * np.random.randn(N_frame))
        else:
            logger.error('Unknown kind of noise "{}"'.format(self.ui.noise))
        if type(self.ui.noi) == complex:
            self.xf = self.xf.astype(complex) + noi
        else:
            self.xf += noi
        # Add DC to stimulus when visible / enabled
        if self.ui.ledDC.isVisible:
            if type(self.ui.DC) == complex:
                self.xf = self.xf.astype(complex) + self.ui.DC
            else:
                self.xf += self.ui.DC

        return self.xf[:N_frame]
Exemple #25
0
 def __init__(self, a):
     super(Sinc, self).__init__(domain=(-np.inf, np.inf))
     self.calc = lambda t: sinc(a*t)
Exemple #26
0
import numpy
from matplotlib import pyplot
from ex3a_funcs import fraunhofer, single_slit
from scipy.special import sinc

lam = 500e-9
d = 100e-6
D = 1
L = 5e-3

N = 2**9

A = single_slit(L, d, N)
y, I = fraunhofer(A, L, N)

pyplot.clf()
pyplot.plot(y * d, I, '--', label='Computed')
pyplot.plot(y * d, sinc(d * y)**2, label='Theoretical')
pyplot.xlabel('$y d / (\lambda D)$')
pyplot.ylabel('$I/I_0$')
pyplot.legend()
pyplot.savefig('core_task1.pdf')
Exemple #27
0
def slepian(M, width, sym=True):
    """Return a digital Slepian (DPSS) window.

    Used to maximize the energy concentration in the main lobe.  Also called
    the digital prolate spheroidal sequence (DPSS).

    Parameters
    ----------
    M : int
        Number of points in the output window. If zero or less, an empty
        array is returned.
    width : float
        Bandwidth
    sym : bool, optional
        When True, generates a symmetric window, for use in filter design.
        When False, generates a periodic window, for use in spectral analysis.

    Returns
    -------
    w : ndarray
        The window, with the maximum value always normalized to 1

    Examples
    --------
    Plot the window and its frequency response:

    >>> from scipy import signal
    >>> from scipy.fftpack import fft, fftshift
    >>> import matplotlib.pyplot as plt

    >>> window = signal.slepian(51, width=0.3)
    >>> plt.plot(window)
    >>> plt.title("Slepian (DPSS) window (BW=0.3)")
    >>> plt.ylabel("Amplitude")
    >>> plt.xlabel("Sample")

    >>> plt.figure()
    >>> A = fft(window, 2048) / (len(window)/2.0)
    >>> freq = np.linspace(-0.5, 0.5, len(A))
    >>> response = 20 * np.log10(np.abs(fftshift(A / abs(A).max())))
    >>> plt.plot(freq, response)
    >>> plt.axis([-0.5, 0.5, -120, 0])
    >>> plt.title("Frequency response of the Slepian window (BW=0.3)")
    >>> plt.ylabel("Normalized magnitude [dB]")
    >>> plt.xlabel("Normalized frequency [cycles per sample]")

    """
    if (M * width > 27.38):
        raise ValueError("Cannot reliably obtain slepian sequences for"
              " M*width > 27.38.")
    if M < 1:
        return np.array([])
    if M == 1:
        return np.ones(1, 'd')
    odd = M % 2
    if not sym and not odd:
        M = M + 1

    twoF = width / 2.0
    alpha = (M - 1) / 2.0
    m = np.arange(0, M) - alpha
    n = m[:, np.newaxis]
    k = m[np.newaxis, :]
    AF = twoF * special.sinc(twoF * (n - k))
    [lam, vec] = linalg.eig(AF)
    ind = np.argmax(abs(lam), axis=-1)
    w = np.abs(vec[:, ind])
    w = w / max(w)

    if not sym and not odd:
        w = w[:-1]
    return w
Exemple #28
0
 def interpolant(t):
     return np.sum(signal*sinc((t - ts)/dt))