Spaces:
Runtime error
Runtime error
File size: 7,917 Bytes
879145e 635855f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
import streamlit as st
import pandas as pd
import numpy as np
from scipy.signal import butter, lfilter, cheby1
import plotly.graph_objects as go
import matplotlib.pyplot as plt
# Function to apply FFT
def apply_fft(data, sampling_rate):
n = len(data)
fft_result = np.fft.fft(data)
freq = np.fft.fftfreq(n, 1 / sampling_rate)
return freq, np.abs(fft_result)
# Function to apply Wiener filter
def apply_wiener_filter(noisy_signal, noise_level):
signal_power = np.mean(noisy_signal ** 2)
noise_power = noise_level ** 2
transfer_function = 1 - noise_power / signal_power
filtered_signal = noisy_signal * transfer_function
return filtered_signal
# Function to apply IIR filter
def apply_iir_filter(data, cutoff_freq, sampling_rate, filter_type='butter'):
nyquist = 0.5 * sampling_rate
normal_cutoff = cutoff_freq / nyquist
if filter_type == 'butter':
b, a = butter(4, normal_cutoff, btype='low', analog=False)
elif filter_type == 'chebyshev':
b, a = cheby1(4, 0.5, normal_cutoff, btype='low', analog=False)
else:
raise ValueError("Invalid filter type")
filtered_data = lfilter(b, a, data)
return filtered_data
# Function to classify motor signal
def classify_motor_signal(data, sampling_rate, noise_level):
_, fft_result = apply_fft(data, sampling_rate)
num_components = 5
threshold_multiplier = 1.5
# Calculate mean amplitude of the first few frequency components
first_few_amplitudes = np.abs(fft_result[1:num_components + 1])
mean_first_few_amplitude = np.mean(first_few_amplitudes)
# Calculate mean amplitude of the entire FFT spectrum
mean_total_amplitude = np.mean(np.abs(fft_result))
# Calculate the ratio of mean_first_few_amplitude to mean_total_amplitude
ratio = mean_first_few_amplitude / mean_total_amplitude
# Set the threshold based on the ratio
threshold = threshold_multiplier
if ratio > threshold:
return "Faulty Motor: High-frequency components detected."
else:
return "Healthy Motor: No significant fault detected."
# Function to generate power spectrum
def generate_power_spectrum(signal, sampling_rate):
n = len(signal)
frequencies = np.fft.fftfreq(n, d=1/sampling_rate)
spectrum = np.abs(np.fft.fft(signal))
return frequencies, spectrum
# Function to identify peak in the power spectrum
def identify_peak(frequencies, spectrum):
peak_frequency = frequencies[np.argmax(spectrum)]
peak_amplitude = np.max(spectrum)
return peak_frequency, peak_amplitude
def calculate_mean_variance(data):
mean_value = np.mean(data)
variance_value = np.var(data)
return mean_value, variance_value
def apply_tukey_test(data, threshold=1.5):
q75, q25 = np.percentile(data, [75, 25])
iqr = q75 - q25
lower_bound = q25 - threshold * iqr
upper_bound = q75 + threshold * iqr
outliers = (data < lower_bound) | (data > upper_bound)
return outliers
# Function to classify motor based on mean, variance, and Tukey test
def classify_motor_stats(data):
mean_value, variance_value = calculate_mean_variance(data)
outliers = apply_tukey_test(data)
if np.any(outliers):
return "Faulty Motor: Outliers detected."
else:
return "Healthy Motor: No significant outliers detected."
# Streamlit app
def main():
st.title("Motor Signal Analysis App")
# Define tabs for different scenarios
tab_names = ["No Load - Healthy", "No Load - Faulty", "Full Load - Healthy", "Full Load - Faulty"]
selected_tab = st.radio("Select Scenario", tab_names)
# Set default values
default_noise_level = 0.1
default_cutoff_freq = 50
# Upload CSV file
uploaded_file = st.file_uploader(f"Upload CSV for {selected_tab}", type=["csv"])
if uploaded_file is not None:
# Load data
df = pd.read_csv(uploaded_file)
data_column = df.columns[0] # Assume data is in the first column
data = df[data_column].values
# Display original signal graph
st.subheader("Original Signal")
original_trace = go.Scatter(x=df.index, y=df[data_column], mode='lines', name='Original Signal')
st.plotly_chart([original_trace])
# Sampling rate
sampling_rate = st.number_input("Enter the sampling rate", min_value=1, value=1000)
# Apply FFT
freq, fft_result = apply_fft(data, sampling_rate)
# Plot FFT
st.subheader("FFT Analysis")
fft_trace = go.Scatter(x=np.abs(freq), y=np.abs(fft_result), mode='lines', name='FFT Result')
# Set layout parameters
layout_fft = go.Layout(
title='FFT Result Analysis',
xaxis=dict(title='Frequency (Hz)', range=[0, 200]), # Set the range up to 200 Hz
yaxis=dict(title='Amplitude',range=[0,20000]), # Remove or comment out 'autorange' setting
)
st.plotly_chart(go.Figure(data=[fft_trace], layout=layout_fft))
# Apply selected filter
apply_filter_option = st.checkbox("Apply Filter")
if apply_filter_option:
# Cutoff frequency for IIR filter
cutoff_freq = st.number_input("Enter the cutoff frequency", min_value=1, value=default_cutoff_freq)
# Filter type for IIR filter
filter_type = st.selectbox("Select Filter Type", ['butter', 'chebyshev', 'wiener'], index=0)
# Apply selected filter
if filter_type == 'butter':
filtered_data = apply_iir_filter(fft_result, cutoff_freq, sampling_rate, filter_type='butter')
elif filter_type == 'chebyshev':
filtered_data = apply_iir_filter(fft_result, cutoff_freq, sampling_rate, filter_type='chebyshev')
elif filter_type == 'wiener':
filtered_data = apply_wiener_filter(fft_result, default_noise_level)
# Generate power spectrum after applying filter
frequencies_spectrum, spectrum = generate_power_spectrum(filtered_data, sampling_rate)
# Identify peak in power spectrum
peak_frequency, peak_amplitude = identify_peak(frequencies_spectrum, spectrum)
# Plot the results using Plotly
st.subheader(f"{filter_type.capitalize()} Filtered Signal")
filtered_trace = go.Scatter(x=np.abs(freq), y=np.abs(filtered_data), mode='lines',
name=f'{filter_type.capitalize()} Filtered Signal')
layout_filtered = go.Layout(
title='Filtered signal',
xaxis=dict(title='Frequency (Hz)',range=[0,200]),
yaxis=dict(title='Amplitude',range=[0,20000]), # Remove or comment out 'autorange' setting
)
st.plotly_chart(go.Figure(data=[filtered_trace], layout=layout_filtered))
st.subheader(f"Power Spectrum after {filter_type.capitalize()} Filter")
power_spectrum_trace = go.Scatter(x=frequencies_spectrum, y=np.abs(spectrum), mode='lines',
name=f'Power Spectrum ({filter_type.capitalize()} Filter)')
# Set layout parameters for power spectrum plot
layout_power_spectrum = go.Layout(
title=f'Power Spectrum after {filter_type.capitalize()} Filter',
xaxis=dict(title='Frequency (Hz)'),
yaxis=dict(title='Amplitude'),
)
st.plotly_chart(go.Figure(data=[power_spectrum_trace], layout=layout_power_spectrum))
# Display peak frequency and amplitude
st.subheader("Peak in Power Spectrum")
st.write(f"Frequency: {peak_frequency} Hz, Amplitude: {peak_amplitude}")
motor_status_stats = classify_motor_stats(data=data)
st.info(f"Motor Status (Mean, Variance, Tukey Test): {motor_status_stats}")
# Run the app
if __name__ == "__main__":
main()
|