11from PyQt5 .QtCore import QThread , Qt , pyqtSignal
22from PyQt5 .QtGui import QPalette , QPainter , QPen
33from PyQt5 .QtWidgets import QWidget
4- from pylsl import StreamInlet , resolve_streams
4+ from pylsl import StreamInlet , resolve_streams , cf_string
55import math
66
7- class dataThread (QThread ):
7+
8+ class DataThread (QThread ):
89 updateStreamNames = pyqtSignal (list , int )
910 sendSignalChunk = pyqtSignal (int , list )
1011
@@ -14,37 +15,42 @@ def __init__(self, parent):
1415 self .streams = []
1516 self .chunk_idx = 0
1617 self .seconds_per_screen = 2
17-
18- def updateStreams (self ):
18+ self .metadata = []
19+ self .srate = None
20+ self .chunkSize = None
21+ self .downSampling = None
22+ self .downSamplingFactor = None
23+ self .downSamplingBuffer = None
24+ self .inlet = None
25+ self .sig_strm_idx = None
26+
27+ def update_streams (self ):
1928 if not self .streams :
2029 self .streams = resolve_streams (wait_time = 1.0 )
21-
22- if self .streams :
23- self .stream_idx = - 1
24- self .metadata = [None ] * len (self .streams )
25-
26- for k in range (len (self .streams )):
27- self .metadata [k ] = {
28- "name" : self .streams [k ].name (),
29- "ch_count" : self .streams [k ].channel_count (),
30- "ch_format" : self .streams [k ].channel_format (),
31- "srate" : self .streams [k ].nominal_srate ()
32- }
33-
34- if self .streams [k ].channel_format () != "String" and self .stream_idx == - 1 :
35- self .stream_idx = k
36-
37- self .srate = int (self .streams [self .stream_idx ].nominal_srate ())
30+ self .sig_strm_idx = - 1
31+ for k , stream in enumerate (self .streams ):
32+ self .metadata .append ({
33+ "name" : stream .name (),
34+ "ch_count" : stream .channel_count (),
35+ "ch_format" : stream .channel_format (),
36+ "srate" : stream .nominal_srate ()
37+ })
38+ if self .sig_strm_idx == - 1 and stream .channel_format () not in ["String" , cf_string ]:
39+ self .sig_strm_idx = k
40+
41+ if self .sig_strm_idx != - 1 :
42+ sig_stream = self .streams [self .sig_strm_idx ]
43+ self .srate = int (sig_stream .nominal_srate ())
3844 self .downSampling = False if self .srate <= 1000 else True
3945 self .chunkSize = round (self .srate / self .chunksPerScreen * self .seconds_per_screen )
4046
4147 if self .downSampling :
4248 self .downSamplingFactor = round (self .srate / 1000 )
43- self .downSamplingBuffer = [[0 for m in range (int (self . streams [ self . stream_idx ] .channel_count ()))]
44- for n in range (round (self .chunkSize / self .downSamplingFactor ))]
49+ self .downSamplingBuffer = [[0 for m in range (int (sig_stream .channel_count ()))]
50+ for n in range (round (self .chunkSize / self .downSamplingFactor ))]
4551
46- self .inlet = StreamInlet (self . streams [ self . stream_idx ] )
47- self .updateStreamNames .emit (self .metadata , self .stream_idx )
52+ self .inlet = StreamInlet (sig_stream )
53+ self .updateStreamNames .emit (self .metadata , self .sig_strm_idx )
4854 self .start ()
4955
5056 def run (self ):
@@ -54,12 +60,11 @@ def run(self):
5460 if timestamps :
5561
5662 if self .downSampling :
57- for k in range (int (self .streams [self .stream_idx ].channel_count ())):
63+ for k in range (int (self .streams [self .sig_strm_idx ].channel_count ())):
5864 for m in range (round (self .chunkSize / self .downSamplingFactor )):
59- endIdx = min ((m + 1 ) * self .downSamplingFactor , len (chunk ))
60- buf = [chunk [n ][k ] for n in range (m * self .downSamplingFactor , endIdx )]
65+ end_idx = min ((m + 1 ) * self .downSamplingFactor , len (chunk ))
66+ buf = [chunk [n ][k ] for n in range (m * self .downSamplingFactor , end_idx )]
6167 self .downSamplingBuffer [m ][k ] = sum (buf ) / len (buf )
62-
6368 self .sendSignalChunk .emit (self .chunk_idx , self .downSamplingBuffer )
6469 else :
6570 self .sendSignalChunk .emit (self .chunk_idx , chunk )
@@ -69,6 +74,7 @@ def run(self):
6974 else :
7075 self .chunk_idx = 0
7176
77+
7278class PaintWidget (QWidget ):
7379
7480 def __init__ (self , widget ):
@@ -86,20 +92,20 @@ def __init__(self, widget):
8692 self .setAutoFillBackground (True )
8793 self .setPalette (pal )
8894
89- self .dataTr = dataThread (self )
90- self .dataTr .sendSignalChunk .connect (self .getDataChunk )
95+ self .dataTr = DataThread (self )
96+ self .dataTr .sendSignalChunk .connect (self .get_data_chunk )
9197
92- def getDataChunk (self , chunkIdx , buffer ):
98+ def get_data_chunk (self , chunk_idx , buffer ):
9399 if not self .mean :
94- self .mean = [0 for k in range (len (buffer [0 ]))]
100+ self .mean = [0 for k in range (len (buffer [0 ]))]
95101 self .scaling = [0 for k in range (len (buffer [0 ]))]
96102 self .dataBuffer = buffer
97103
98- self .idx = chunkIdx
104+ self .idx = chunk_idx
99105 self .update (self .idx * (self .width () / self .dataTr .chunksPerScreen ) - self .interval ,
100- 0 ,
101- self .width () / self .dataTr .chunksPerScreen ,
102- self .height ())
106+ 0 ,
107+ self .width () / self .dataTr .chunksPerScreen ,
108+ self .height ())
103109
104110 def paintEvent (self , event ):
105111 if self .dataBuffer :
@@ -137,15 +143,15 @@ def paintEvent(self, event):
137143 if self .lastY :
138144 if not math .isnan (self .lastY [k ]) and not math .isnan (self .dataBuffer [0 ][k ]):
139145 painter .drawLine (self .idx * (self .width () / self .dataTr .chunksPerScreen ) - self .interval ,
140- - self .lastY [k ] + (k + 0.5 ) * self .channelHeight ,
141- self .idx * (self .width () / self .dataTr .chunksPerScreen ),
142- - self .dataBuffer [0 ][k ] + (k + 0.5 ) * self .channelHeight )
146+ - self .lastY [k ] + (k + 0.5 ) * self .channelHeight ,
147+ self .idx * (self .width () / self .dataTr .chunksPerScreen ),
148+ - self .dataBuffer [0 ][k ] + (k + 0.5 ) * self .channelHeight )
143149
144150 for m in range (len (self .dataBuffer ) - 1 ):
145151 if not math .isnan (self .dataBuffer [m ][k ]) and not math .isnan (self .dataBuffer [m + 1 ][k ]):
146152 painter .drawLine (m * self .interval + self .idx * (self .width () / self .dataTr .chunksPerScreen ),
147- - self .dataBuffer [m ][k ] + (k + 0.5 ) * self .channelHeight ,
148- (m + 1 ) * self .interval + self .idx * (self .width () / self .dataTr .chunksPerScreen ),
149- - self .dataBuffer [m + 1 ][k ] + (k + 0.5 ) * self .channelHeight )
153+ - self .dataBuffer [m ][k ] + (k + 0.5 ) * self .channelHeight ,
154+ (m + 1 )* self .interval + self .idx * (self .width () / self .dataTr .chunksPerScreen ),
155+ - self .dataBuffer [m + 1 ][k ] + (k + 0.5 ) * self .channelHeight )
150156
151157 self .lastY = self .dataBuffer [- 1 ]
0 commit comments