def detect_modulation(data: np.ndarray,
                      wavelet_scale=4,
                      median_filter_order=11) -> str:
    n_data = len(data)
    data = data[np.abs(data) > 0]
    if len(data) == 0:
        return None

    if n_data - len(data) > 3:
        return "OOK"

    data = data / np.abs(np.max(data))
    mag_wavlt = np.abs(Wavelet.cwt_haar(data, scale=wavelet_scale))
    if len(mag_wavlt) == 0:
        return None

    norm_mag_wavlt = np.abs(
        Wavelet.cwt_haar(data / np.abs(data), scale=wavelet_scale))

    var_mag = np.var(mag_wavlt)
    var_norm_mag = np.var(norm_mag_wavlt)

    var_filtered_mag = np.var(
        c_auto_interpretation.median_filter(mag_wavlt, k=median_filter_order))
    var_filtered_norm_mag = np.var(
        c_auto_interpretation.median_filter(norm_mag_wavlt,
                                            k=median_filter_order))

    if all(v < 0.15 for v in (var_mag, var_norm_mag, var_filtered_mag,
                              var_filtered_norm_mag)):
        return "OOK"

    if var_mag > 1.5 * var_norm_mag:
        # ASK or QAM
        # todo: consider qam, compare filtered mag and filtered norm mag
        return "ASK"
    else:
        # FSK or PSK
        if var_mag > 5 * var_filtered_mag:
            return "PSK"
        else:
            # Now we either have a FSK signal or we a have OOK single pulse
            # If we have an FSK, there should be at least two peaks in FFT
            fft = np.fft.fft(data[0:2**int(np.log2(len(data)))])
            fft = np.abs(np.fft.fftshift(fft))
            ten_greatest_indices = np.argsort(fft)[::-1][0:10]
            greatest_index = ten_greatest_indices[0]
            min_distance = 10
            min_freq = 100  # 100 seems to be magnitude of noise frequency

            if any(
                    abs(i -
                        greatest_index) >= min_distance and fft[i] >= min_freq
                    for i in ten_greatest_indices):
                return "FSK"
            else:
                return "OOK"
Beispiel #2
0
def detect_modulation(data: np.ndarray, wavelet_scale=4, median_filter_order=11) -> str:
    n_data = len(data)
    data = data[np.abs(data) > 0]
    if len(data) == 0:
        return None

    if n_data - len(data) > 3:
        return "OOK"

    data = data / np.abs(np.max(data))
    mag_wavlt = np.abs(Wavelet.cwt_haar(data, scale=wavelet_scale))
    if len(mag_wavlt) == 0:
        return None

    norm_mag_wavlt = np.abs(Wavelet.cwt_haar(data / np.abs(data), scale=wavelet_scale))

    var_mag = np.var(mag_wavlt)
    var_norm_mag = np.var(norm_mag_wavlt)

    var_filtered_mag = np.var(c_auto_interpretation.median_filter(mag_wavlt, k=median_filter_order))
    var_filtered_norm_mag = np.var(c_auto_interpretation.median_filter(norm_mag_wavlt, k=median_filter_order))

    if all(v < 0.1 for v in (var_mag, var_norm_mag, var_filtered_mag, var_filtered_norm_mag)):
        return "OOK"

    if var_mag > 1.5 * var_norm_mag:
        # ASK or QAM
        # todo: consider qam, compare filtered mag and filtered norm mag
        return "ASK"
    else:
        # FSK or PSK
        if var_mag > 10 * var_filtered_mag:
            return "PSK"
        else:
            # Now we either have a FSK signal or we a have OOK single pulse
            # If we have an FSK, there should be at least two peaks in FFT
            fft = np.fft.fft(data[0:2 ** int(np.log2(len(data)))])
            fft = np.abs(np.fft.fftshift(fft))
            ten_greatest_indices = np.argsort(fft)[::-1][0:10]
            greatest_index = ten_greatest_indices[0]
            min_distance = 10
            min_freq = 100  # 100 seems to be magnitude of noise frequency

            if any(abs(i - greatest_index) >= min_distance and fft[i] >= min_freq for i in ten_greatest_indices):
                return "FSK"
            else:
                return "OOK"