1
+ from pylsl import StreamInlet , resolve_stream
2
+ import numpy as np
3
+ from scipy .signal import welch
4
+ from scipy .integrate import simpson
5
+ import time
6
+
7
+ # Define the bandpower function
8
+ def bandpower (data , sf , band , window_sec = None , relative = False ):
9
+ band = np .asarray (band )
10
+ low , high = band
11
+
12
+ if window_sec is not None :
13
+ nperseg = window_sec * sf
14
+ else :
15
+ nperseg = (2 / low ) * sf
16
+
17
+ freqs , psd = welch (data , sf , nperseg = nperseg )
18
+ freq_res = freqs [1 ] - freqs [0 ] #Frequency resolution by simpson
19
+ idx_band = np .logical_and (freqs >= low , freqs <= high )
20
+ bp = simpson (psd [idx_band ], dx = freq_res )
21
+
22
+ if relative :
23
+ bp /= simpson (psd , dx = freq_res )
24
+ return bp
25
+
26
+ def normalize (value , min_value , max_value ):
27
+ """Normalize a value to a range [0, 1] based on min and max values."""
28
+ return (value - min_value ) / (max_value - min_value ) if max_value > min_value else 0
29
+
30
+ def eeg_data_thread (eeg_queue ):
31
+ print ("Looking for an LSL stream..." )
32
+ streams = resolve_stream ('name' , 'BioAmpDataStream' )
33
+ if not streams :
34
+ print ("No LSL stream found!" )
35
+ return
36
+
37
+ inlet = StreamInlet (streams [0 ])
38
+ sampling_frequency = 250
39
+ bands = {'Delta' : [0.5 , 4 ], 'Theta' : [4 , 8 ], 'Alpha' : [8 , 13 ], 'Beta' : [13 , 30 ], 'Gamma' : [30 , 40 ]}
40
+ buffer_length = sampling_frequency * 4
41
+ data_buffer = {'Channel1' : [], 'Channel2' : []}
42
+ powerData1 = []
43
+ powerData2 = []
44
+ c = 0
45
+ start_time = time .time ()
46
+
47
+ baseline1 = baseline2 = 1 # Initialize baselines
48
+ min_power1 = min_power2 = 0
49
+ max_power1 = max_power2 = 1
50
+
51
+ while True :
52
+ sample , timestamp = inlet .pull_sample ()
53
+ if len (sample ) == 2 :
54
+ data_buffer ['Channel1' ].append (sample [0 ])
55
+ data_buffer ['Channel2' ].append (sample [1 ])
56
+ if len (data_buffer ['Channel1' ]) > buffer_length :
57
+ data_buffer ['Channel1' ].pop (0 )
58
+ data_buffer ['Channel2' ].pop (0 )
59
+
60
+ elapsed_time = time .time () - start_time
61
+ if len (data_buffer ['Channel1' ]) >= buffer_length :
62
+ power_data = {'Channel1' : {}, 'Channel2' : {}}
63
+ for band_name , band_freqs in bands .items ():
64
+ power_data ['Channel1' ][band_name ] = bandpower (np .array (data_buffer ['Channel1' ]), sampling_frequency , band_freqs )
65
+ power_data ['Channel2' ][band_name ] = bandpower (np .array (data_buffer ['Channel2' ]), sampling_frequency , band_freqs )
66
+
67
+ powerData1 .append (power_data ['Channel1' ]['Beta' ] / power_data ['Channel1' ]['Alpha' ])
68
+ powerData2 .append (power_data ['Channel2' ]['Beta' ] / power_data ['Channel2' ]['Alpha' ])
69
+ if elapsed_time >= 5 :
70
+ if c != 1 :
71
+ baseline1 = max (powerData1 )
72
+ baseline2 = max (powerData2 )
73
+ # min_power1 = min(powerData1)
74
+ # max_power1 = baseline1
75
+ # min_power2 = min(powerData2)
76
+ # max_power2 = baseline2
77
+ c = 1
78
+ data_time = elapsed_time
79
+ powerData1 = []
80
+ powerData2 = []
81
+ elif elapsed_time - data_time >= 0.25 :
82
+ current_power1 = (max (powerData1 )- baseline1 )/ baseline1
83
+ current_power2 = (max (powerData2 )- baseline2 )/ baseline2
84
+ # normalized_power1 = normalize(current_power1, min_power1, max_power1)
85
+ # normalized_power2 = normalize(current_power2, min_power2, max_power2)
86
+ eeg_queue .put ((current_power1 , current_power2 ))
87
+ powerData1 = []
88
+ powerData2 = []
89
+ data_time = elapsed_time
0 commit comments