6
6
import numpy as np
7
7
import csv
8
8
from datetime import datetime
9
+
9
10
import numpy as np
10
11
11
12
from PySide6 .QtWidgets import QApplication , QWidget , QGraphicsScene , QFileDialog
26
27
27
28
from utils .data_processing_lib import lFilter , lFilter_moving_average
28
29
from utils .devices import serialPort
29
- from datetime import datetime
30
+ from utils . external_sync import External_Sync
30
31
31
- global live_acquisition_flag , hold_acquisition_thread , nChannels
32
+
33
+ global live_acquisition_flag , hold_acquisition_thread , nChannels , temp_filename
32
34
live_acquisition_flag = False
33
35
hold_acquisition_thread = True
34
36
nChannels = 4
@@ -49,6 +51,7 @@ def load_ui(self):
49
51
self .ui .exp_loaded = False
50
52
51
53
# Default params
54
+ self .ui .ext_sync_flag = False
52
55
self .ui .fs = 250 #sampling rate
53
56
self .ui .baudrate = 2000000
54
57
@@ -99,10 +102,14 @@ def load_ui(self):
99
102
self .ui .listWidget_expConditions .currentItemChanged .connect (self .update_exp_condition )
100
103
101
104
self .myFig = None
102
- self .temp_filename = "temp.csv"
105
+
106
+ global temp_filename
107
+ temp_utc_sec = str ((datetime .now () - datetime (1970 , 1 , 1 )).total_seconds ())
108
+ temp_utc_sec = temp_utc_sec .replace ('.' , '_' )
109
+ temp_filename = temp_utc_sec + "_temp.csv"
103
110
self .csv_header = ['' ]
104
111
self .ui .write_eventcode = ''
105
- self .csvfile = open (self . temp_filename , 'w' , encoding = "utf" , newline = "" )
112
+ self .csvfile = open (temp_filename , 'w' , encoding = "utf" , newline = "" )
106
113
self .writer = csv .writer (self .csvfile )
107
114
108
115
ui_file .close ()
@@ -150,6 +157,14 @@ def load_exp_params(self):
150
157
self .csv_header = self .ui .channels + ["arduino_ts" , "event_code" ]
151
158
self .writer .writerow (self .csv_header )
152
159
160
+ # External Sync
161
+ self .ui .ext_sync_flag = self .ui .params_dict ["external_sync" ]["enable" ]
162
+ if self .ui .ext_sync_flag :
163
+ self .ui .sync_role = self .ui .params_dict ["external_sync" ]["role" ]
164
+ self .ui .sync_ip = self .ui .params_dict ["external_sync" ]["tcp_ip" ]
165
+ self .ui .sync_port = self .ui .params_dict ["external_sync" ]["tcp_port" ]
166
+ self .ui .sync_obj = External_Sync (self .ui .sync_role , self .ui .sync_ip , self .ui .sync_port )
167
+
153
168
self .ui .exp_loaded = True
154
169
self .ui .pushButton_exp_params .setEnabled (False )
155
170
self .ui .label_status .setText ("Loaded experiment parameters successfully" )
@@ -168,6 +183,7 @@ def load_exp_params(self):
168
183
169
184
def addData_callbackFunc (self , value ):
170
185
# print("Add data: " + str(value))
186
+
171
187
self .myFig .addData (value )
172
188
173
189
if self .ui .data_record_flag :
@@ -184,13 +200,14 @@ def addData_callbackFunc(self, value):
184
200
185
201
186
202
def stop_record_process (self ):
203
+ global temp_filename
187
204
if not self .csvfile .closed :
188
205
self .csvfile .close ()
189
206
time .sleep (1 )
190
207
self .save_file_path = os .path .join (self .ui .data_root_dir , self .ui .pid + "_" +
191
208
self .ui .curr_exp_name + '_' + self .ui .curr_exp_condition + '_' + self .ui .utc_sec + '.csv' )
192
- if os .path .exists (self . temp_filename ):
193
- shutil .move (self . temp_filename , self .save_file_path )
209
+ if os .path .exists (temp_filename ):
210
+ shutil .move (temp_filename , self .save_file_path )
194
211
self .ui .label_status .setText ("Recording stopped and data saved for: Exp - " + self .ui .curr_exp_name + "; Condition - " + self .ui .curr_exp_condition )
195
212
else :
196
213
self .ui .label_status .setText ("Error saving data" )
@@ -205,7 +222,7 @@ def stop_record_process(self):
205
222
self .myFig .event_toggle = True
206
223
207
224
# prepare for next recording
208
- self .csvfile = open (self . temp_filename , 'w' , encoding = "utf" , newline = "" )
225
+ self .csvfile = open (temp_filename , 'w' , encoding = "utf" , newline = "" )
209
226
self .writer = csv .writer (self .csvfile )
210
227
self .writer .writerow (self .csv_header )
211
228
@@ -254,7 +271,7 @@ def connect_serial_port(self):
254
271
255
272
256
273
def start_acquisition (self ):
257
- global live_acquisition_flag
274
+ global live_acquisition_flag , temp_filename
258
275
if not live_acquisition_flag :
259
276
live_acquisition_flag = True
260
277
if not self .ppgDataLoop_started :
@@ -274,12 +291,12 @@ def start_acquisition(self):
274
291
# To reset the graph and clear the values
275
292
276
293
self .myFig .reset_draw ()
277
- if os .path .exists (self . temp_filename ):
294
+ if os .path .exists (temp_filename ):
278
295
if not self .csvfile .closed :
279
296
self .csvfile .close ()
280
- os .remove (self . temp_filename )
297
+ os .remove (temp_filename )
281
298
282
- self .csvfile = open (self . temp_filename , 'w' , encoding = "utf" , newline = "" )
299
+ self .csvfile = open (temp_filename , 'w' , encoding = "utf" , newline = "" )
283
300
self .writer = csv .writer (self .csvfile )
284
301
self .writer .writerow (self .csv_header )
285
302
@@ -290,14 +307,29 @@ def start_acquisition(self):
290
307
self .ui .listWidget_expConditions .setEnabled (True )
291
308
292
309
293
-
294
- def record_data (self ):
295
- if not self .ui .data_record_flag :
296
- if not os .path .exists (self .temp_filename ):
297
- self .csvfile = open (self .temp_filename , 'w' , encoding = "utf" , newline = "" )
298
- self .writer = csv .writer (self .csvfile )
299
- self .writer .writerow (self .csv_header )
310
+ def start_record_process (self ):
311
+
312
+ global temp_filename
313
+ self .ui .pushButton_record_data .setText ("Staring to Record..." )
314
+ self .ui .pushButton_record_data .setEnabled (False )
315
+
316
+ if not os .path .exists (temp_filename ):
317
+ self .csvfile = open (temp_filename , 'w' , encoding = "utf" , newline = "" )
318
+ self .writer = csv .writer (self .csvfile )
319
+ self .writer .writerow (self .csv_header )
320
+
321
+ sync_signal = False
322
+ if self .ui .ext_sync_flag :
323
+ if self .ui .sync_role == "server" :
324
+ self .ui .label_status .setText ("Server is ready, waiting for external sync to start recording" )
325
+ sync_signal = self .ui .sync_obj .run_server ()
326
+ elif self .ui .sync_role == "client" :
327
+ self .ui .sync_obj .run_client ()
328
+ sync_signal = True
329
+ else :
330
+ sync_signal = True
300
331
332
+ if sync_signal :
301
333
self .ui .record_start_time = datetime .now ()
302
334
self .ui .data_record_flag = True
303
335
@@ -306,6 +338,8 @@ def record_data(self):
306
338
307
339
# self.ui.utc_timestamp_signal = datetime.utcnow()
308
340
self .ui .pushButton_record_data .setText ("Stop Recording" )
341
+ self .ui .pushButton_record_data .setEnabled (True )
342
+
309
343
if self .ui .timed_acquisition :
310
344
self .ui .label_status .setText ("Timed Recording started for: Exp - " + self .ui .curr_exp_name + "; Condition - " + self .ui .curr_exp_condition + "; Max-Time: " + str (self .ui .max_acquisition_time ))
311
345
else :
@@ -314,11 +348,18 @@ def record_data(self):
314
348
self .ui .lineEdit_Event .setEnabled (True )
315
349
self .ui .pushButton_Event .setEnabled (True )
316
350
self .ui .event_status = False
351
+
317
352
try :
318
353
self .ui .eventcode = int (self .ui .lineEdit_Event .text ())
319
354
except :
320
355
self .ui .label_status .setText ("Incorrect entry for evencode, using eventcode = 0" )
321
356
self .ui .eventcode = 0
357
+
358
+
359
+ def record_data (self ):
360
+ if not self .ui .data_record_flag :
361
+ start_record_thread = threading .Thread (name = 'start_record' , target = self .start_record_process , daemon = True )
362
+ start_record_thread .start ()
322
363
323
364
else :
324
365
self .ui .data_record_flag = False
@@ -401,16 +442,11 @@ def reset_draw(self):
401
442
402
443
403
444
def addData (self , value ):
404
- global live_acquisition_flag
405
- val_filt = []
406
- for nCh in range (self .nChannels ):
407
- val_filt .append (self .filt_objs [str (nCh )].lfilt (value [nCh ]))
445
+ self .count_frame += 1
408
446
409
- if live_acquisition_flag :
410
- self .count_frame += 1
411
- for nCh in range (self .nChannels ):
412
- self .plot_signals [nCh ] = np .roll (self .plot_signals [nCh ], - 1 )
413
- self .plot_signals [nCh ][- 1 ] = val_filt [nCh ]
447
+ for nCh in range (self .nChannels ):
448
+ self .plot_signals [nCh ] = np .roll (self .plot_signals [nCh ], - 1 )
449
+ self .plot_signals [nCh ][- 1 ] = self .filt_objs [str (nCh )].lfilt (value [nCh ])
414
450
return
415
451
416
452
@@ -510,9 +546,8 @@ def main(app):
510
546
ret = app .exec ()
511
547
del widget
512
548
513
- fn = "temp.csv"
514
- if os .path .exists (fn ):
515
- os .remove (fn )
549
+ if os .path .exists (temp_filename ):
550
+ os .remove (temp_filename )
516
551
517
552
# sys.exit(ret)
518
553
return
0 commit comments