Python from scratch - PAL
111 subscribers
84 photos
5 videos
6 files
51 links
Download Telegram
.
جلسه هجدهم ..............................................
.
پردازش سیگنال‌های مغزی EEG, LFP

.
❤2🙏1
.

اصول پردازش سیگنال EEG و LFP با پایتون


به طور کلی اصول تحلیل برای هر دو سیگنال EEG و LFP یکسان است.

تفاوت در ماهیت سیگنال‌ها است که باعث می‌شود نوع پیش‌پردازش و تحلیل کمی متفاوت باشد.

در پایتون، ابزارها یکسان‌اند ولی تنظیمات فیلتر، انتخاب باند فرکانسی و نوع پیش‌پردازش فرق می‌کند.

.
.
برخی شباهت‌های سیگنال EEG و LFP

هر دو سیگنال زمان–وابسته هستند (Time series).

هر دو معمولاً نیاز به فیلتر کردن نویز دارند.

مثلاً Notch filter برای برق شهر و یا فیلتر Band-pass برای محدوده فرکانسی مورد نظر

تحلیل‌هایی مثل FFT (طیف فرکانسی)، Wavelet، توان باند فرکانسی (Delta, Theta, Alpha, Beta, Gamma) برای هر دو انجام می‌شود.

ابزارهای رایج در پایتون مثل scipy.signal، mne یا neurodsp قابل استفاده برای هر دو هستند.

.
.
مقایسه بین بین EEG و LFP

.
❤1
آشنایی با سیگنال

.
❤1
.
تعریف سیگنال

سیگنال هر کمیت فیزیکی است که با زمان تغییر کند و حامل اطلاعات باشد.

مثال‌


سیگنال EEG و LFP (ولتاژ)

صدای انسان (امواج صوتی)

ضربان قلب (ECG)

نور چشمک‌زن (پالس‌های نوری)

.
.
سیگنال پیوسته در برابر گسسته


سیگنال پیوسته (Continuous)

در هر لحظه از زمان تعریف شده.

به عبارت دیگر یک سیگنال آنالوگ است.

مثال: سیگنال مغزی واقعی که الکترود ثبت می‌کند (یک ولتاژ واقعی با زمان).

نمایش ریاضی: x(t)


سیگنال گسسته (Discrete)

فقط در زمان‌های مشخص (sample points) ثبت می‌شود.

برای تحلیل در کامپیوتر همیشه باید سیگنال پیوسته به گسسته تبدیل شود.

به عبارت دیگر سیگنال در کامپیوتر به شکل گسسته یا دیجیتال است.

نمایش ریاضی: x[n]

نکته: فرایند تبدیل پیوسته به گسسته را نمونه‌برداری (Sampling) می‌گوییم.


.
.
نویز (Noise)


هر سیگنال علاوه بر بخش مفید، نویز هم دارد.

انواع نویز:

- نویز برق شهر (50Hz or 60Hz)
معمولاً یک موج سینوسی خالص است با فرکانس 50 هرتز در ایران یا 60 هرتز در آمریکا.
این نویز به سیگنال‌های مغزی مثل EEG یا LFP اضافه می‌شود و معمولاً با Notch filter حذف می‌شود.

- نویز سفید (White Noise)
سیگنالی تصادفی است که توان آن در همه‌ی فرکانس‌ها یکسان است.
هیچ فرکانسی غالب نیست، مثل صدای رادیوی بدون کانال.
به عبارت دیگر توان یکنواخت در همه فرکانس‌ها

- نویز حرارتی (Random white noise)
نام دیگر آن Johnson-Nyquist noise است.
ناشی از حرکت تصادفی الکترون‌ها در رسانا به علت دمای غیر صفر.
مثل نویز سفید رفتار می‌کند (فرکانس غالب ندارد)، اما شدتش به دما بستگی دارد.

- نویز حرکتی (Artifact از حرکت بدن/الکترود)


مثال در سیگنال LFP و EEG


وقتی حیوان حرکت می‌کند، الکترود حرکت کرده و نویز مکانیکی ایجاد می‌شود.

.
.
فیلترها (Filters)


فیلتر ابزاری است برای حذف بخش‌های ناخواسته یا استخراج بخش‌های مفید سیگنال.

1- نوع Low-pass filter فقط فرکانس‌های پایین‌تر از یک مقدار خاص را عبور می‌دهد.

کاربرد: حذف نویز فرکانس بالا


2- نوع High-pass filter فقط فرکانس‌های بالاتر را عبور می‌دهد.

کاربرد: حذف تغییرات کند (با فرکانس پایین)


3- نوع Band-pass filter یک بازه خاص از فرکانس‌ها را نگه می‌دارد.

مثال: در EEG می‌خواهیم فقط موج گاما (30–80 Hz) را ببینیم. در این حالت از Band-pass استفاده می‌کنیم.


4- نوع Notch filter فقط یک فرکانس خاص را حذف می‌کند.

مثال: حذف نویز برق شهر 50 Hz

.
.
مثال عملی با پایتون (JupyterLab)


فرض کنید یک سیگنال شبیه‌سازی شده داریم شامل تتا (6Hz) + نویز سفید + نویز برق شهر 50Hz

ابتدا با اجرای کد زیر سیگنال پر از نویز را می‌بینیم.

سپس در ردیف دوم فقط باند تتا بعد از فیلتر شدن را می‌بینیم.

.
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, filtfilt

# Sampling settings
fs = 500 # Sampling frequency (Hz)
t = np.linspace(0, 2, fs*2, endpoint=False) # 2 seconds duration

# Original signal: Theta oscillation (6 Hz)
theta = np.sin(2*np.pi*6*t)

# Noise components: random noise + 50Hz line noise
noise = 0.5 * np.random.randn(len(t))
line_noise = np.sin(2*np.pi*50*t)
lfp_raw = theta + noise + line_noise

# Define band-pass filter (to keep only 4-12 Hz)
def bandpass_filter(data, low, high, fs, order=4):
nyq = 0.5 * fs # Nyquist frequency
b, a = butter(order, [low/nyq, high/nyq], btype="band")
return filtfilt(b, a, data) # Apply filter forward & backward

# Apply filter to raw signal
lfp_filtered = bandpass_filter(lfp_raw, 4, 12, fs)

# Plotting
plt.figure(figsize=(12,6))

plt.subplot(2,1,1)
plt.plot(t, lfp_raw)
plt.title("Raw LFP (Theta + Noise)")
plt.ylabel("Amplitude")

plt.subplot(2,1,2)
plt.plot(t, lfp_filtered, color="red")
plt.title("Filtered LFP (Theta band 4-12Hz)")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")

plt.tight_layout()
plt.show()
❤2
.
مشاهده نتیجه

.
.
کد زیر که سیگنالی شامل دو جزء است را اجرا کنید:
- یک موج اصلی 10 Hz (شبیه LFP واقعی)
- نویز برق 50 Hz
نتیجه اجرای کد در تصویر است.👆

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

# Sampling rate and time vector
fs = 1000 # Hz
t = np.linspace(0, 1, fs, endpoint=False)

# Create signal: 10 Hz + 50 Hz noise
clean = np.sin(2*np.pi*10*t)
line_noise = 0.5 * np.sin(2*np.pi*50*t)
noisy_signal = clean + line_noise

# Plot the noisy signal
plt.figure(figsize=(10,4))
plt.plot(t, noisy_signal, label="Noisy Signal")
plt.plot(t, clean, 'r--', label="Clean (10 Hz)")
plt.legend()
plt.title("Simulated LFP with 50 Hz Line Noise")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.tight_layout()
plt.show()
ادامه دارد.
🙏2
.
نویز برق شهر
import numpy as np
import matplotlib.pyplot as plt

# --- Parameters ---
fs = 1000 # Sampling frequency (Hz)
t = np.linspace(0, 1, fs) # 1 second duration
f_power = 50 # Power line frequency (Hz)
amplitude = 1.0 # Amplitude

# --- Generate pure 50 Hz noise ---
power_noise = amplitude * np.sin(2 * np.pi * f_power * t)

# --- FFT (Frequency Spectrum) ---
freqs = np.fft.rfftfreq(len(t), 1/fs)
spectrum = np.abs(np.fft.rfft(power_noise)) / len(t)

# --- Plot ---
plt.figure(figsize=(12,5))

# Time domain
plt.subplot(1,2,1)
plt.plot(t, power_noise, color="red")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.title("50 Hz Power Line Noise (Time Domain)")
plt.xlim(0, 0.1) # zoom in to see cycles

# Frequency domain
plt.subplot(1,2,2)
plt.stem(freqs, spectrum, basefmt=" ")
plt.xlabel("Frequency (Hz)")
plt.ylabel("Amplitude")
plt.title("Frequency Spectrum (Peak at 50 Hz)")
plt.xlim(0, 100) # only show up to 100 Hz

plt.tight_layout()
plt.show()
.
نویز برق شهر

سمت چپ: در Time Domain محور افقی زمان است، سیگنال را به صورت تغییر دامنه برحسب زمان می‌بینیم.
در زمان موج سینوسی قرمز بالا و پایین می‌رود.
در فرکانس فقط یک پیک واضح در 50Hz ظاهر می‌شود.


سمت راست: در FFT Domain (Frequency Domain) با کمک Fast Fourier Transform (FFT) سیگنال را تجزیه می‌کنیم و می‌بینیم انرژی یا توان آن در چه فرکانس‌هایی متمرکز است.
.
.
مفهوم Sampling Rate (نرخ نمونه‌برداری)


سیگنال‌های واقعی (مثل صدا یا EEG) پیوسته هستند.

برای پردازش با کامپیوتر باید آنها را به شکل گسسته (Discrete) ذخیره کنیم.

نرخ نمونه‌برداری یا Sampling rate (fs) یعنی چند بار در ثانیه از سیگنال نمونه‌برداری می‌کنیم.

مثلا fs = 100 Hz یعنی در هر ثانیه 100 نقطه از سیگنال برداشته می‌شود.

هرچقدر fs بیشتر باشد، سیگنال دقیق‌تر ذخیره می‌شود.

اگر fs کم باشد سیگنال "خوب دیده نمی‌شود.

برای فهم دقیق‌تر این موضوع کد زیر را اجرا کنید. 👇


.