diff --git a/mysignal/__init__.py b/mysignal/__init__.py index 60eb1af..d83c2a9 100644 --- a/mysignal/__init__.py +++ b/mysignal/__init__.py @@ -1 +1 @@ -__version__ = '0.1.18' +__version__ = '0.1.19' diff --git a/mysignal/phasefreq.py b/mysignal/phasefreq.py index 782d3b7..b633e74 100644 --- a/mysignal/phasefreq.py +++ b/mysignal/phasefreq.py @@ -70,7 +70,7 @@ def filter_signal_by_modes(time, signal, num_modes=1, bandwidth_factor=0.1, requ bandwidth = bandwidth_factor * freq lowcut = max(0.01, freq - bandwidth) # Éviter les fréquences négatives highcut = freq + bandwidth - + # Éviter les fréquences supérieures à la fréquence de Nyquist nyq = 0.5 * fs highcut = min(highcut, nyq * 0.99) # Laisser une marge @@ -78,18 +78,18 @@ def filter_signal_by_modes(time, signal, num_modes=1, bandwidth_factor=0.1, requ # Normaliser les fréquences lowcut_norm = lowcut / nyq highcut_norm = highcut / nyq - + print(f"Filtrage à {freq:.2f} Hz, bande : [{lowcut_norm:.5f}, {highcut_norm:.5f}] (normalisé)") - + # Vérifier si le signal est suffisamment long period = 1 / lowcut if lowcut > 0 else 0 #required_cycles = 40 # Vous avez mentionné 40 cycles min_length = required_cycles * period * fs - + if len(signal_clean) < min_length: print(f"Avertissement: Signal court pour {freq:.2f} Hz. " f"Requis: {min_length:.0f} échantillons, Disponible: {len(signal_clean)}") - + # Méthode alternative: utiliser un filtre SOS (Second-Order Sections) # plus stable pour les signaux courts sos = butter(4, [lowcut_norm, highcut_norm], btype='band', output='sos') @@ -98,7 +98,7 @@ def filter_signal_by_modes(time, signal, num_modes=1, bandwidth_factor=0.1, requ # Méthode standard b, a = butter(4, [lowcut_norm, highcut_norm], btype='band') filtered_signal = filtfilt(b, a, signal_clean) - + filtered_signals.append(filtered_signal) # Le temps reste le même après filtrage @@ -107,17 +107,17 @@ def filter_signal_by_modes(time, signal, num_modes=1, bandwidth_factor=0.1, requ return np.array(filtered_signals), dominant_freqs, time_filtered -def plot_filtered_modes(t, e, e_filtered, e_frequencies, e_time, n_modes): +def plot_filtered_modes(t, e, e_filtered, e_frequencies, e_time, n_modes, output=None): fig, ax = plt.subplots(nrows=n_modes+1, ncols=2, figsize=(12, 4 * n_modes), gridspec_kw={'width_ratios': [3, 1]}) - + ax[0, 0].plot(t, e) ax[0, 0].set_title('Signal original') ax[0, 0].set_xlabel('Temps (s)') ax[0, 0].set_ylabel('Amplitude') - - - + + + for i in range(n_modes): ax[i+1, 0].plot(e_time, e_filtered[i]) ax[i+1, 0].set_title(f'Mode #{i+1} filtré ({e_frequencies[i]:.2f} Hz)') @@ -126,10 +126,12 @@ def plot_filtered_modes(t, e, e_filtered, e_frequencies, e_time, n_modes): ax[i+1, 1].plot(e_time, e, color='red') ax[i+1, 1].plot(e_time, e_filtered[i]) - + ax[i+1, 1].set_xlim(left=0.5 * e_time.mean(), right=0.5*e_time.mean() + 10/e_frequencies[i]) plt.tight_layout() plt.show() + if output: + plt.savefig(output) @@ -238,7 +240,7 @@ def analyze_signal_Hilbert(time, e_signal, s_signal, freq_rtol=0.01): period_e = 1 / freq_e period_s = 1 / freq_s - + res = {'period_e': period_e, 'period_s': period_s, @@ -247,7 +249,7 @@ def analyze_signal_Hilbert(time, e_signal, s_signal, freq_rtol=0.01): 'phase': mean_phase_diff, 'phrase_deg': phase_diff_deg, 'delay': time_shift} - + return res def analyze_signal_sinfit(time, e_signal, s_signal, freq_rtol=0.01): @@ -344,7 +346,7 @@ def analyze_signal_sinfit(time, e_signal, s_signal, freq_rtol=0.01): period_e = 1 / freq_e period_s = 1 / freq_s - + res = {'period_e': period_e, 'period_s': period_s, 'freq_e': freq_e, @@ -352,7 +354,7 @@ def analyze_signal_sinfit(time, e_signal, s_signal, freq_rtol=0.01): 'phase': phase_diff, 'phrase_deg': phase_diff_deg, 'delay': time_shift} - + return res @@ -460,7 +462,7 @@ def analyze_signal_cross_correlation(time, e_signal, s_signal, freq_rtol=0.01): 'phase': phase_diff, 'phrase_deg': phase_diff_deg, 'delay': time_shift} - + return res @@ -571,18 +573,18 @@ def analyze_signal_wavelet(time, e_signal, s_signal, freq_rtol=0.01): 'phase': mean_phase_diff, 'phrase_deg': phase_diff_deg, 'delay': time_shift} - + return res def plot_phases(e_time, e_filtered, e_frequencies, s_filtered, n_modes, callback=analyze_signal_wavelet): fig, ax = plt.subplots(nrows=n_modes, ncols=2, figsize=(12, 6), gridspec_kw={'width_ratios': [3, 1]}) - - + + for mod in range(n_modes): - + res = callback(e_time, e_filtered[mod], s_filtered[mod], freq_rtol=0.3) - + ax[mod, 0].set_title(f'Freq: {res['freq_e']:.3f}, Phase: {res['phase']:.3f}, Delay: {res['delay']:.3f}' ) ax[mod, 0].plot(e_time, e_filtered[mod], label='e') ax[mod, 0].plot(e_time, s_filtered[mod], label='s') @@ -592,9 +594,11 @@ def plot_phases(e_time, e_filtered, e_frequencies, s_filtered, n_modes, callback ax[mod, 1].plot(e_time, e_filtered[mod], label='e') ax[mod, 1].plot(e_time, s_filtered[mod], label='s') ax[mod, 1].set_xlim(left=0.5 * e_time.mean(), right=0.5*e_time.mean() + 10/e_frequencies[mod]) - + for a in ax[:, 0]: a.legend() - + plt.tight_layout(); - plt.show(); \ No newline at end of file + plt.show(); + if output: + plt.savefig(output)