Пример #1
0
def PSD(sig, fs=None, window='hann', window_length=8192, weighting=False, inputspec=True):
    """
    Calculate Spectral Density Spectrum [W]
    Inputs:
        sig = time or spectrum - Default is spectrum
        fs = [Hz] sample frequency - only valid when time signal
            (inputspec=False)
    Outputs:
        F = [Hz] frequency bins
        PSD = [W?] Power spectral density - power per hertz
    Options:
        window = [string] name of windowtype - Only valid when inputspec is
                time (False)
        window_length = [-] length of window in number of samples - Only valid
                        when inputspec is time (False)
        weighting = True/False Boolean for setting if a weighting is applied on
                    spectrum - only valid when inputspec is time(False)
        inputspec = True/False Boolean for setting input as spectrum(True) or
                    as time Signal(False)

    AS creates a single sided spectrum of Frequency and phase.
    There two possible input signals. a time signal and a spectral signal
    (complex or Real and Imaginair).

    When time signal is applied some extra parameters can be set.
    window and weighting.
    For window it is possible to set the window type and length of samples.
    default for this is hanning window and length of 8192 samples.
    after this the single sided power spectrum is created and returned.

    When input is a spectrum. it is checked for complex vallued signal and for
    symmetry.
    after this the single sided power spectrum is created and returned.
    """
    if inputspec is True:
        from scripts.checks import istuple, even, odd, oddphase, phasecheck
        if istuple(sig):
            sig1phase = phasecheck(sig[1])
            if sig1phase is True:
                sig0even = even(sig[0])
                sig1odd = oddphase(sig[1])
                if (sig0even is True) and (sig1odd is True):
                    N = len(sig)
                    F = np.arange(1, N / 2)
                    PS = (sig[0][1:len(sig[0]) / 2] ** 2) / F
                    # power per Hertz
                    PH = sig[1][1:len(sig[1])/2]
                else:
                    N = len(sig)
                    F = np.arange(1, N / 2)
                    PS = (sig[0] ** 2) / F  # power per hertz
                    PH = sig[1]
            else:
                sig0even = even(sig[0])
                sig1odd = odd(sig[1])
                if (sig0even is True) and (sig1odd is True):
                    N = len(sig)
                    F = np.arange(1, N/2)
                    PS = (np.sqrt(sig[0][1:len(sig[0]) / 2] ** 2 + sig[1][1:len(sig[1]) / 2] ** 2) ** 2) / F
                    PH = np.arctan2(sig[0][1:len(sig[0]) / 2], sig[1][1:len(sig[1]) / 2])
                else:
                    N = len(sig)
                    F = np.arange(1, N / 2)
                    PS = (np.sqrt(sig[0] ** 2 + sig[1] ** 2) ** 2) / F
                    # power per hertz
                    PH = np.arctan2(sig[0], sig[1])
        elif np.iscomplex(sig):
            print('from complex spectum is becomming a magnitude pahse spectrum... \nshow olny N/2 frequency bins')
            N = len(sig)
            F = np.arange(1, N / 2)
            PSD = (abs(sig[1:N / 2]) ** 2) / F  # power per hertz
            PH = np.arctan2(sig.real, sig.imag)
    elif inputspec is False:
        F, PSD, PH = AS(sig, fs, window, window_length, weighting, inputspec)
        PSD = (PSD ** 2) / F  # Power per hertz - AS to PSD 
    else:
        raise ValueError('inputspec should be True or False')
    return(F, PSD, PH)
Пример #2
0
def AS(sig, fs=None, window='hann', window_length=8192, weighting=False, inputspec=True):
    """
    Calculate Amplitude Spectrum [v // g // ...]
    Inputs:
        sig = time or spectrum - Default is spectrum (Magnitude, Phase)
        fs = [Hz] sample frequency - only valid when time signal
            (inputspec=False)
    Outputs:
        F = [Hz] Frequency Array of given frequencies - only availeble in time
            input
        AS = [V, g,...] amplitude spectrum depends on input
        PH = [deg] phase output -180 - 180 degrees phase
    Options:
        window = [string] name of windowtype - Only valid when inputspec is
                time (False)
        window_length = [-] length of window in number of samples - Only valid
                        when inputspec is time (False)
        weighting = True/False Boolean for setting if a weighting is applied on
                    spectrum - only valid when inputspec is time(False)
        inputspec = True/False Boolean for setting input as spectrum(True) or
                    as time Signal(False)

    AS creates a single sided spectrum of Frequency and phase.
    There two possible input signals. a time signal and a spectral signal
    (complex or Real and Imaginair).

    When time signal is applied some extra parameters can be set.
    window and weighting.
    For window it is possible to set the window type and length of samples.
    default for this is hanning window and length of 8192 samples.
    When window_length is set to None; no window will be applied
    after this the single sided amplitude spectrum is created and returned.

    When input is a spectrum. it is checked for complex vallued signal and for
    symmetry.
    after this the single sided amplitude spectrum is created and returned.
    """
    if inputspec is True:
        from scripts.checks import istuple, even, odd, oddphase, phasecheck
        if istuple(sig):
            sig1phase = phasecheck(sig[1])
            if sig1phase is True:
                sig0even = even(sig[0])
                sig1odd = oddphase(sig[1])
                if (sig0even is True) and (sig1odd is True):
                    N = len(sig)
                    F = np.arange(1, N / 2)
                    AS = sig[0][1:len(sig[0])/2]
                    PH = sig[1][1:len(sig[1])/2]
                else:
                    N = len(sig)
                    F = np.arange(1, N / 2)
                    AS = sig[0]
                    PH = sig[1]
            else:
                sig0even = even(sig[0])
                sig1odd = odd(sig[1])
                if (sig0even is True) and (sig1odd is True):
                    N = len(sig)
                    F = np.arange(1, N / 2)
                    AS = np.sqrt(sig[0][1:len(sig[0]) / 2] ** 2 + sig[1][1:len(sig[1]) / 2] ** 2)
                    PH = np.arctan2(sig[0][1:len(sig[0]) / 2], sig[1][1:len(sig[1]) / 2])
                else:
                    N = len(sig)
                    F = np.arange(1, N / 2)
                    AS = np.sqrt(sig[0] ** 2 + sig[1] ** 2)
                    PH = np.arctan2(sig[0], sig[1])
        elif np.iscomplex(sig):
            print('from complex spectum is becomming a magnitude pahse spectrum... \nshow olny N/2 frequency bins')
            N = len(sig)
            AS = abs(sig[1:N / 2])
            PH = np.arctan2(sig.real, sig.imag)
            F = np.arange(1, N / 2)
    elif inputspec is False:
        if fs is not None:
            pass
        else:
            raise ValueError('value fs is \'None\' this should be changed')

        if (window_length is None) and (weighting is False):
            F, AS, PH = FFT(sig, fs, spectrum='AmPh0')
        elif (window_length is None) and (weighting is not False):
            F, AS, PH = FFT(sig, fs, spectrum='AmPh')
        elif isinstance(window_length, int) and (weighting is False):
            F, AS, PH = FFT(sig, fs, window, window_length, spectrum='AmPh0')
        elif isinstance(window_length, int) and (weighting is not False):
            F, AS, PH = FFT(sig, fs, window, window_length, spectrum='AmPh')

        if weighting is False:
            pass
        elif weighting is True:
            from scripts.weighting import AWeighting
            AS = AWeighting.A_Weighting(F, AS)
        elif weighting == 'A':
            from scripts.weighting import AWeighting
            AS = AWeighting.A_Weighting(F, AS)
        elif weighting == 'B':
            from scripts.weighting import BWeighting
            AS = BWeighting.B_Weighting(F, AS)
        elif weighting == 'C':
            from scripts.weighting import CWeighting
            AS = CWeighting.C_Weighting(F, AS)
        elif weighting == 'D':
            from scripts.weighting import DWeighting
            AS = DWeighting.D_Weighting(F, AS)
        else:
            raise ValueError('weighing should be True, False, or the letters A to D')
    else:
        raise ValueError('inputspec should be True or False')
    return(F, AS, PH)
Пример #3
0
def Transfer(x_in, x_out, fs):  # possible some input paremeters addded later
    """
    Inputs:
        x_in = input signal or recorded signal
        x_out = output signal or calculated signal
        fs = [Hz] sample frequency
    Output:
        H_0 = derived signal X_in / x_out

    Before makeing the transfer the input data is checked if it exist out the
    right information. This means the data have to be frequency specific data.
    This data exist out of amplitude and phase info from the form \' Real\'
    and \'Imaginair\' or complex data.

    transfer function is in case of in = microphone and out is ref signal:
        in signal     in1    in2     blackbox out
    H = ---------- --> --- or --- is ------------
        out signal     out    out     blackbox in
    2 Do:
        - Check complex values
        - check equal sized
        - if complex than no FFT
    """
    # Tuple = FFT or wrong input
    # Compex valued signals = FFT
    # Nummeric is real valued and neeed FFT!!
    # else is wrong valued type and give error
    from scripts.checks import even, odd, oddphase, phasecheck

    if isinstance(x_in, tuple):
        if phasecheck(x_in[1]) == True:
            x_in0even = even(x_in[0])  # even symmetry
            x_in1phodd = oddphase(x_in[1])  # odd symmetry
        else:
            x_in0even = even(x_in[0])  # even symmetry
            x_in1odd = odd(x_in[1])  # odd symmetry
            print(x_in0even, x_in1odd)
        # make complex array
        if (x_in0even & x_in1odd):
            x_in = x_in[0] + 1j*x_in[1]
        elif (x_in0even & x_in1phodd):
            x_in = x_in[0]*np.sin(x_in[1]) + 1j * x_in[0]*np.cos(x_in[1])
        if isinstance(x_out, tuple):
            x_out0even = even(x_out[0])
            x_out1odd = odd(x_out[1])
            # make complex array
            if (x_out0even & x_out1odd):
                x_out = x_out[0] + 1j*x_out[0]
                H_0 = x_in / x_out
        elif np.iscomplexobj(x_out):
            H_0 = x_in / x_out
        elif np.isrealobj(x_out):
            (X_OUT, F, _) = FFT(x_out, fs)
            H_0 = x_in / X_OUT
        else:
            raise TypeError("Wrong input type")
    elif np.iscomplexobj(x_in):
        if isinstance(x_out, tuple):
            x_in0even = even(x_in[0])  # even symmetry
            x_in1odd = odd(x_in[1])  # odd symmetry
            # make complex array
            if (x_out0even & x_out1odd):
                x_out = x_out[0] + 1j*x_out[0]
                H_0 = x_in / x_out
        elif np.iscomplexobj(x_out):
            H_0 = x_in / x_out
        elif np.isrealobj(x_out):
            (F, X_OUT, _) = FFT(x_out, fs)
            H_0 = x_in / X_OUT
        else:
            raise TypeError("Wrong input type")
    elif np.isrealobj(x_in):
        (F, X_IN, _) = FFT(x_in, fs)
        if isinstance(x_out, tuple):
            x_in0even = even(x_in[0])  # even symmetry
            x_in1odd = odd(x_in[1])  # odd symmetry
            # make complex array
            if (x_out0even & x_out1odd):
                x_out = x_out[0] + 1j*x_out[0]
                H_0 = X_IN / x_out
        elif np.iscomplexobj(x_out):
            H_0 = X_IN / x_out
        elif np.isrealobj(x_out):
            (F, X_OUT, _) = FFT(x_out, fs)
            H_0 = X_IN / X_OUT
        else:
            raise TypeError("Wrong input type")
    else:
        raise TypeError("Wrong input type")
    return(H_0)