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"
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"