@@ -111,7 +111,7 @@ def __init__(
111111 self ,
112112 host = "127.0.0.1" ,
113113 port = 5556 ,
114- expected_fs = 5000 .0 ,
114+ expected_fs = 0 .0 ,
115115 emg_channels = 0 ,
116116 emg_stream_name = "OpenEphys_EMG" ,
117117 imu_stream_name = "OpenEphys_IMU" ,
@@ -148,6 +148,7 @@ def __init__(
148148 self .last_mag_std = 0.0
149149 self .last_chunk = 0
150150 self .last_error = ""
151+ self .detected_fs = 0.0 # filled after connect
151152 self ._prev_written = 0 # track ref-channel total_samples_written
152153
153154 def _wait_for_channels (self , timeout = 3.0 ):
@@ -214,7 +215,15 @@ def start(self):
214215 ch_idx = detected [: self .emg_channels ]
215216 self .client .set_channel_index (ch_idx )
216217
217- fs = float (self .client .fs ) if float (self .client .fs ) > 0 else self .expected_fs
218+ # Infer sampling rate from the stream (client.fs is updated from ZMQ headers)
219+ client_fs = float (self .client .fs )
220+ if client_fs > 0 and (self .expected_fs <= 0 or self .expected_fs == 5000.0 ):
221+ self .detected_fs = client_fs
222+ elif self .expected_fs > 0 :
223+ self .detected_fs = self .expected_fs
224+ else :
225+ self .detected_fs = client_fs if client_fs > 0 else 2000.0
226+ fs = self .detected_fs
218227 self .emg_outlet , self .imu_outlet = build_outlets (
219228 self .emg_stream_name , self .imu_stream_name , fs , self .emg_channels
220229 )
@@ -461,7 +470,10 @@ def _init_ui(self):
461470 cg .addWidget (self .ch_edit , 1 , 1 )
462471
463472 cg .addWidget (QLabel ("Fs (Hz)" ), 1 , 2 )
464- self .fs_edit = QLineEdit (str (int (self .args .fs )))
473+ self .fs_edit = QSpinBox ()
474+ self .fs_edit .setRange (0 , 100000 )
475+ self .fs_edit .setSpecialValueText ("Auto" )
476+ self .fs_edit .setValue (int (self .args .fs ))
465477 self .fs_edit .setFixedWidth (80 )
466478 cg .addWidget (self .fs_edit , 1 , 3 )
467479
@@ -531,10 +543,7 @@ def _build_streamer(self):
531543 host = self .host_edit .text ().strip () or self .args .host
532544 port = self .port_edit .value ()
533545 channels = self .ch_edit .value ()
534- try :
535- fs = float (self .fs_edit .text ().strip ())
536- except ValueError :
537- fs = self .args .fs
546+ fs = float (self .fs_edit .value ())
538547 emg_name = self .emg_name .text ().strip () or self .args .emg_stream_name
539548 imu_name = self .imu_name .text ().strip () or self .args .imu_stream_name
540549 return OpenEphysLSLStreamer (
@@ -577,8 +586,10 @@ def _on_start(self):
577586
578587 self .status .setText ("Streaming" )
579588 self .status .setStyleSheet ("color: #44ff44; font-weight: bold; font-size: 14px;" )
580- # Update channel count from auto-detection
589+ # Update channel count and fs from auto-detection
581590 self .ch_edit .setValue (self .streamer .emg_channels )
591+ if self .streamer .detected_fs > 0 :
592+ self .fs_edit .setValue (int (self .streamer .detected_fs ))
582593 self .reminder .hide ()
583594 self .btn_start .setEnabled (False )
584595 self .btn_stop .setEnabled (True )
@@ -620,8 +631,9 @@ def _tick(self):
620631 try :
621632 info = self .streamer .poll_once ()
622633 ch = info ["channels" ]
634+ fs_str = f"{ self .streamer .detected_fs :.0f} " if self .streamer .detected_fs > 0 else "?"
623635 self .samples .setText (
624- f"Samples: { info ['total_emg' ]:,} | chunk ({ ch } , { info ['chunk' ]} )"
636+ f"Samples: { info ['total_emg' ]:,} | chunk ({ ch } ch , { info ['chunk' ]} ) @ { fs_str } Hz "
625637 )
626638 if info ["chunk" ] > 0 :
627639 self .emg_stats .setText (
@@ -659,7 +671,10 @@ def run_cli(args):
659671 imu_transport = args .imu_transport ,
660672 )
661673 streamer .start ()
662- print (f"Streaming LSL: EMG='{ args .emg_stream_name } ', IMU='{ args .imu_stream_name } '" )
674+ print (
675+ f"Streaming LSL: EMG='{ args .emg_stream_name } ', IMU='{ args .imu_stream_name } '"
676+ f" | { streamer .emg_channels } ch @ { streamer .detected_fs :.0f} Hz"
677+ )
663678 try :
664679 while True :
665680 info = streamer .poll_once ()
@@ -682,7 +697,10 @@ def build_arg_parser():
682697 p .add_argument ("--host" , default = "127.0.0.1" , help = "Open Ephys ZMQ host" )
683698 p .add_argument ("--port" , type = int , default = 5556 , help = "Open Ephys ZMQ data port" )
684699 p .add_argument (
685- "--fs" , type = float , default = 5000.0 , help = "Expected EMG sampling rate"
700+ "--fs" ,
701+ type = float ,
702+ default = 0.0 ,
703+ help = "Sampling rate in Hz (0 = auto-detect from stream)" ,
686704 )
687705 p .add_argument (
688706 "--channels" , type = int , default = 0 , help = "EMG channel count (0 = auto-detect)"
0 commit comments