source: trunk/Puzzlebox/Synapse/Session.py @ 370

Last change on this file since 370 was 370, checked in by sc, 8 years ago

Session:

  • splitting shared routines out of Interface
File size: 49.5 KB
Line 
1# -*- coding: utf-8 -*-
2
3# Copyright Puzzlebox Productions, LLC (2010-2012)
4#
5# This code is released under the GNU Pulic License (GPL) version 2
6# For more information please refer to http://www.gnu.org/copyleft/gpl.html
7
8__changelog__ = """\
9Last Update: 2012.04.01
10"""
11
12__todo__ = """
13- update configuration.ini file with settings entered into interface
14"""
15
16### IMPORTS ###
17import os, sys, time
18
19import Puzzlebox.Synapse.Configuration as configuration
20
21if configuration.ENABLE_PYSIDE:
22        try:
23                import PySide as PyQt4
24                from PySide import QtCore, QtGui, QtNetwork
25        except Exception, e:
26                print "ERROR: Exception importing PySide:",
27                print e
28                configuration.ENABLE_PYSIDE = False
29        else:
30                print "INFO: [Synapse:Interface] Using PySide module"
31
32if not configuration.ENABLE_PYSIDE:
33        print "INFO: [Synapse:Interface] Using PyQt4 module"
34        from PyQt4 import QtCore, QtGui, QtNetwork
35
36
37#try:
38        #from Interface_Plot import *
39        #MATPLOTLIB_AVAILABLE = True
40#except Exception, e:
41        #print "ERROR: Exception importing Interface_Plot:",
42        #print e
43        #MATPLOTLIB_AVAILABLE = False
44
45
46#if (sys.platform == 'win32'):
47        #import _winreg as winreg
48        #import itertools
49        #import re
50        #import serial
51        #DEFAULT_IMAGE_PATH = 'images'
52#elif (sys.platform == 'darwin'):
53        #DEFAULT_IMAGE_PATH = 'images'
54#else:
55        #import bluetooth
56        #DEFAULT_IMAGE_PATH = '/usr/share/puzzlebox_synapse/images'
57
58
59try:
60        import cPickle as pickle
61except:
62        import pickle
63
64#from Interface_Design import Ui_Form as Design
65
66#import Puzzlebox.Synapse.Client as synapse_client
67#import Puzzlebox.Synapse.ThinkGear.Server as thinkgear_server
68#import Puzzlebox.Synapse.Emotiv.Server as emotiv_server
69#import puzzlebox_logger
70
71
72#####################################################################
73# Globals
74#####################################################################
75
76DEBUG = configuration.DEBUG
77
78SYNAPSE_SERVER_HOST = configuration.SYNAPSE_SERVER_HOST
79SYNAPSE_SERVER_PORT = configuration.SYNAPSE_SERVER_PORT
80
81EMULATE_THINKGEAR_FOR_EMOTIV = configuration.EMULATE_THINKGEAR_FOR_EMOTIV
82
83PATH_TO_HCITOOL = '/usr/bin/hcitool'
84
85##UPDATE_INTERFACE_VIA_TIMER = True # Alternative is to establish a
86                                  ### ThinkGear Connect client which
87                                  ### updates the interface on demand
88                                  ### as packets are received
89
90#UPDATE_INTERFACE_VIA_TIMER = False
91
92##INTERFACE_UPDATE_FREQUENCY = (1 / 512) * 1000 # ms (512 Hz)
93#INTERFACE_UPDATE_FREQUENCY = 1000 # ms
94
95#INTERFACE_RAW_EEG_UPDATE_FREQUENCY = 512
96
97#PACKET_MINIMUM_TIME_DIFFERENCE_THRESHOLD = 0.75
98
99
100#####################################################################
101# Classes
102#####################################################################
103
104class puzzlebox_synapse_session(QtGui.QWidget):
105       
106        def __init__(self, log, \
107                     #server=None, \
108                     DEBUG=DEBUG, \
109                     parent=None, \
110                     #embedded_mode=False):
111                     ):
112               
113                self.log = log
114                self.DEBUG = DEBUG
115                self.parent=parent
116                #self.embedded_mode=embedded_mode
117               
118                if self.parent == None:
119                        QtGui.QWidget.__init__(self, parent)
120                        #self.setupUi(self)
121               
122                        self.configureSettings()
123                        self.connectWidgets()
124               
125                self.name = "Synapse:Session"
126               
127                #self.synapseServer = None
128                #self.synapseClient = None
129               
130                #self.maxEEGPower = THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE
131               
132                #self.debug_console_buffer = ''
133               
134                #self.packets = {}
135                #self.packets['rawEeg'] = []
136                #self.packets['signals'] = []
137               
138                #self.customDataHeaders = []
139               
140                #if UPDATE_INTERFACE_VIA_TIMER:
141                        #self.updateInterfaceTimer = QtCore.QTimer()
142                        #QtCore.QObject.connect(self.updateInterfaceTimer, \
143                                                    #QtCore.SIGNAL("timeout()"), \
144                                                    #self.updateInterface)
145               
146               
147                if (sys.platform == 'win32'):
148                        self.homepath = os.path.join( \
149                           os.environ['HOMEDRIVE'], \
150                           os.environ['HOMEPATH'], \
151                           'Desktop')
152                elif (sys.platform == 'darwin'):
153                        desktop = os.path.join(os.environ['HOME'], 'Documents')
154                        if os.path.exists(desktop):
155                                self.homepath = desktop
156                        else:
157                                self.homepath = os.environ['HOME']
158                else:
159                        desktop = os.path.join(os.environ['HOME'], 'Desktop')
160                        if os.path.exists(desktop):
161                                self.homepath = desktop
162                        else:
163                                self.homepath = os.environ['HOME']
164               
165               
166                if not os.path.exists(self.homepath):
167                        if self.DEBUG:
168                                print "DEBUG: User default path not found"
169                        self.homepath = os.getcwd()
170               
171               
172                self.activePlugins = []
173       
174       
175        ##################################################################
176       
177        def configureSettings(self):
178               
179                # Synapse Interface
180                #image_path = "puzzlebox.ico"
181                #if not os.path.exists(image_path):
182                        #image_path = os.path.join(DEFAULT_IMAGE_PATH, image_path)
183               
184                #if os.path.exists(image_path):
185                        #icon = QtGui.QIcon()
186                        #icon.addPixmap(QtGui.QPixmap(image_path), \
187                                            #QtGui.QIcon.Normal, \
188                                            #QtGui.QIcon.Off)
189                        #self.setWindowIcon(icon)
190               
191                #image_path = "puzzlebox_logo.png"
192                #if not os.path.exists(image_path):
193                        #image_path = os.path.join(DEFAULT_IMAGE_PATH, image_path)
194                #if os.path.exists(image_path):
195                        #self.labelPuzzleboxIcon.setPixmap(QtGui.QPixmap(image_path))
196               
197               
198                #if configuration.INTERFACE_TAB_POSITION == 'South':
199                        #self.tabWidget.setTabPosition(QtGui.QTabWidget.South)
200                #else:
201                        #self.tabWidget.setTabPosition(QtGui.QTabWidget.North)
202               
203               
204                # EEG Devices
205                #self.updateDevices()
206               
207               
208                # Connect Server
209                #self.textLabelBluetoothStatus.setText("Status: Disconnected")
210               
211                # Display Host for ThinkGear Connect Socket Server
212                #self.lineEditSynapseHost.setText(SYNAPSE_SERVER_HOST)
213               
214                # Display Port for ThinkGear Connect Socket Server
215                #self.lineEditSynapsePort.setText('%i' % SYNAPSE_SERVER_PORT)
216               
217               
218                # ThinkgGear Progress Bars
219                #self.progressBarEEGDelta.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
220                #self.progressBarEEGTheta.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
221                #self.progressBarEEGLowAlpha.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
222                #self.progressBarEEGHighAlpha.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
223                #self.progressBarEEGLowBeta.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
224                #self.progressBarEEGHighBeta.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
225                #self.progressBarEEGLowGamma.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
226                #self.progressBarEEGMidGamma.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
227               
228                #self.progressBarAttention.setMaximum(THINKGEAR_EMULATION_MAX_ESENSE_VALUE)
229                #self.progressBarMeditation.setMaximum(THINKGEAR_EMULATION_MAX_ESENSE_VALUE)
230               
231                #self.progressBarSignalContactQuality.setMaximum(200)
232               
233               
234                #if MATPLOTLIB_AVAILABLE:
235                        #self.rawEEGMatplot = rawEEGMatplotlibCanvas( \
236                                                #self.tabEEGSignals, \
237                                                #width=8, \
238                                                #height=4, \
239                                                #dpi=100, \
240                                                #title='Raw EEG Waves')
241                        #self.chartEEGMatplot = chartEEGMatplotlibCanvas( \
242                                                #self.tabCharts, \
243                                                #width=8, \
244                                                #height=4, \
245                                                #dpi=100, \
246                                                #title='EEG Brain Signals')
247               
248                #else:
249                        #self.tabWidget.removeTab(self.tabWidget.indexOf(self.tabEEGSignals))
250                        #self.tabWidget.removeTab(self.tabWidget.indexOf(self.tabCharts))
251               
252               
253                pass
254       
255       
256        ##################################################################
257       
258        def connectWidgets(self):
259               
260                #self.connect(self.comboBoxEEGHeadsetModel, \
261                             #QtCore.SIGNAL("currentIndexChanged(int)"), \
262                             #self.updateDevices)
263               
264                #self.connect(self.pushButtonBluetoothSearch, \
265                             #QtCore.SIGNAL("clicked()"), \
266                             #self.updateDevices)
267               
268                #self.connect(self.pushButtonSynapseServer, \
269                             #QtCore.SIGNAL("clicked()"), \
270                             #self.startSynapseServer)
271               
272                #self.connect(self.pushButtonSave, \
273                             #QtCore.SIGNAL("clicked()"), \
274                             #self.saveData)
275               
276                #self.connect(self.pushButtonExport, \
277                             #QtCore.SIGNAL("clicked()"), \
278                             #self.exportData)
279               
280                #self.connect(self.pushButtonReset, \
281                             #QtCore.SIGNAL("clicked()"), \
282                             #self.resetData)
283               
284                pass
285       
286       
287        ##################################################################
288       
289        #def startSynapseServer(self):
290               
291                #eeg_headset_model = str(self.comboBoxEEGHeadsetModel.currentText())
292                #device_address = str(self.comboBoxDeviceSelect.currentText())
293                #server_interface = str(self.lineEditSynapseHost.text())
294                #server_port = int(self.lineEditSynapsePort.text())
295               
296               
297                #if ((eeg_headset_model == 'NeuroSky MindWave Mobile') or \
298                    #(eeg_headset_model == 'NeuroSky MindWave') or \
299                    #(eeg_headset_model == 'NeuroSky MindSet')):
300                       
301                        #self.startThinkGearConnectService()
302               
303                #elif (eeg_headset_model == 'Emotiv EPOC'):
304                       
305                        #self.startEmotivService()
306               
307               
308                #if UPDATE_INTERFACE_VIA_TIMER:
309                        #self.updateInterfaceTimer.start(INTERFACE_UPDATE_FREQUENCY)
310               
311                #else:
312                        #self.synapseClient = \
313                                #synapse_client.puzzlebox_synapse_client( \
314                                        #self.log, \
315                                        #server_host=server_interface, \
316                                        #server_port=server_port, \
317                                        #DEBUG=0, \
318                                        #parent=self)
319                       
320                        #self.synapseClient.start()
321               
322               
323                #device_selection = self.comboBoxDeviceSelect.currentText()
324                #self.textLabelBluetoothStatus.setText("Status: Connected")
325                #self.pushButtonBluetoothSearch.setEnabled(False)
326                #self.comboBoxDeviceSelect.setEnabled(False)
327                #self.comboBoxEEGHeadsetModel.setEnabled(False)
328               
329                #self.lineEditSynapseHost.setEnabled(False)
330                #self.lineEditSynapsePort.setEnabled(False)
331               
332                #self.pushButtonSynapseServer.setText('Stop')
333               
334                #self.progressBarEEGDelta.setValue(0)
335                #self.progressBarEEGTheta.setValue(0)
336                #self.progressBarEEGLowAlpha.setValue(0)
337                #self.progressBarEEGHighAlpha.setValue(0)
338                #self.progressBarEEGLowBeta.setValue(0)
339                #self.progressBarEEGHighBeta.setValue(0)
340                #self.progressBarEEGLowGamma.setValue(0)
341                #self.progressBarEEGMidGamma.setValue(0)
342               
343                #self.progressBarAttention.setValue(0)
344                #self.progressBarMeditation.setValue(0)
345               
346               
347                #self.disconnect(self.pushButtonSynapseServer, \
348                                     #QtCore.SIGNAL("clicked()"), \
349                                     #self.startSynapseServer)
350               
351                #self.connect(self.pushButtonSynapseServer, \
352                                  #QtCore.SIGNAL("clicked()"), \
353                                  #self.stopSynapseServer)
354       
355       
356        ##################################################################
357       
358        #def stopSynapseServer(self):
359               
360                #eeg_headset_model = str(self.comboBoxEEGHeadsetModel.currentText())
361                #device_address = str(self.comboBoxDeviceSelect.currentText())
362               
363                #if ((eeg_headset_model == 'NeuroSky MindWave Mobile') or \
364                    #(eeg_headset_model == 'NeuroSky MindWave') or \
365                    #(eeg_headset_model == 'NeuroSky MindSet')):
366                       
367                        #self.stopThinkGearConnectService()
368               
369                #elif (eeg_headset_model == 'Emotiv EPOC'):
370                       
371                        #self.stopEmotivService()
372               
373               
374                #if UPDATE_INTERFACE_VIA_TIMER:
375                        #self.updateInterfaceTimer.stop()
376                #else:
377                        #try:
378                                #self.synapseClient.exitThread()
379                                ##self.synapseClient.disconnectFromHost()
380                        #except Exception, e:
381                                #if self.DEBUG:
382                                        #print "Call failed to self.synapseClient.exitThread():",
383                                        ##print "Call failed to self.synapseClient.disconnectFromHost():",
384                                        #print e
385                       
386                        #try:
387                                #self.synapseServer.exitThread()
388                        #except Exception, e:
389                                #if self.DEBUG:
390                                        #print "Call failed to self.synapseServer.exitThread():",
391                                        #print e
392               
393               
394                #self.disconnect(self.pushButtonSynapseServer, \
395                                #QtCore.SIGNAL("clicked()"), \
396                                #self.stopSynapseServer)
397               
398                #self.connect(self.pushButtonSynapseServer, \
399                                  #QtCore.SIGNAL("clicked()"), \
400                                  #self.startSynapseServer)
401               
402                #self.lineEditSynapseHost.setEnabled(True)
403                #self.lineEditSynapsePort.setEnabled(True)
404               
405                #self.pushButtonSynapseServer.setText('Start')
406               
407                #self.pushButtonBluetoothSearch.setEnabled(True)
408               
409                #self.pushButtonSynapseServer.setChecked(False)
410               
411                #self.textLabelBluetoothStatus.setText("Status: Disconnected")
412               
413                #self.pushButtonBluetoothSearch.setEnabled(True)
414               
415                #self.comboBoxDeviceSelect.setEnabled(True)
416                #self.comboBoxEEGHeadsetModel.setEnabled(True)
417               
418               
419                #self.progressBarEEGDelta.setValue(0)
420                #self.progressBarEEGTheta.setValue(0)
421                #self.progressBarEEGLowAlpha.setValue(0)
422                #self.progressBarEEGHighAlpha.setValue(0)
423                #self.progressBarEEGLowBeta.setValue(0)
424                #self.progressBarEEGHighBeta.setValue(0)
425                #self.progressBarEEGLowGamma.setValue(0)
426                #self.progressBarEEGMidGamma.setValue(0)
427               
428                #self.progressBarAttention.setValue(0)
429                #self.progressBarMeditation.setValue(0)
430               
431                #self.progressBarSignalContactQuality.setValue(0)
432               
433                #self.maxEEGPower = THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE
434               
435                ## In case the user connects to a MindSet, then disconnects
436                ## and re-connects to a MindSet Emulator,
437                ## we need to reset the max power values
438                #self.progressBarEEGDelta.setMaximum(self.maxEEGPower)
439                #self.progressBarEEGTheta.setMaximum(self.maxEEGPower)
440                #self.progressBarEEGLowAlpha.setMaximum(self.maxEEGPower)
441                #self.progressBarEEGHighAlpha.setMaximum(self.maxEEGPower)
442                #self.progressBarEEGLowBeta.setMaximum(self.maxEEGPower)
443                #self.progressBarEEGHighBeta.setMaximum(self.maxEEGPower)
444                #self.progressBarEEGLowGamma.setMaximum(self.maxEEGPower)
445                #self.progressBarEEGMidGamma.setMaximum(self.maxEEGPower)
446       
447       
448        ##################################################################
449       
450        #def startThinkGearConnectService(self):
451               
452                #eeg_headset_model = str(self.comboBoxEEGHeadsetModel.currentText())
453                #device_address = str(self.comboBoxDeviceSelect.currentText())
454                #server_interface = str(self.lineEditSynapseHost.text())
455                #server_port = int(self.lineEditSynapsePort.text())
456                #emulate_headset_data = (device_address == 'ThinkGear Emulator')
457               
458               
459                #self.synapseServer = \
460                        #thinkgear_server.puzzlebox_synapse_server_thinkgear( \
461                                #self.log, \
462                                #server_interface=server_interface, \
463                                #server_port=server_port, \
464                                #device_model=eeg_headset_model, \
465                                #device_address=device_address, \
466                                #emulate_headset_data=emulate_headset_data, \
467                                #DEBUG=DEBUG, \
468                                #parent=self)
469               
470                #self.synapseServer.start()
471       
472       
473        ##################################################################
474       
475        #def stopThinkGearConnectService(self):
476               
477                #pass
478       
479       
480        ##################################################################
481       
482        #def startEmotivService(self):
483               
484                ##eeg_headset_model = str(self.comboBoxEEGHeadsetModel.currentText())
485                #device_address = str(self.comboBoxDeviceSelect.currentText())
486               
487                ##server_host = configuration.EMOTIV_SERVER_HOST
488               
489                #if device_address == 'Emotiv Control Panel':
490                        ##server_port = configuration.EMOTIV_SERVER_PORT_CONTROL_PANEL
491                        #device_address = configuration.EMOTIV_SERVER_PORT_CONTROL_PANEL
492                #else:
493                        ##server_port = configuration.EMOTIV_SERVER_PORT_EMOCOMPOSER
494                        #device_address = configuration.EMOTIV_SERVER_PORT_EMOCOMPOSER
495               
496               
497                #server_interface = str(self.lineEditSynapseHost.text())
498                #server_port = int(self.lineEditSynapsePort.text())
499                #eeg_headset_model = str(self.comboBoxEEGHeadsetModel.currentText())
500                ##device_address = str(self.comboBoxDeviceSelect.currentText())
501                #emulate_headset_data = (device_address == 'ThinkGear Emulator')
502               
503               
504                #self.synapseServer = \
505                        #emotiv_server.puzzlebox_synapse_server_emotiv( \
506                                #self.log, \
507                                #server_interface=server_interface, \
508                                #server_port=server_port, \
509                                #device_model=eeg_headset_model, \
510                                #device_address=device_address, \
511                                #emulate_headset_data=emulate_headset_data, \
512                                #DEBUG=DEBUG, \
513                                #parent=self)
514               
515                #self.synapseServer.start()
516               
517               
518                #self.progressBarEEGDelta.setEnabled(False)
519                #self.progressBarEEGTheta.setEnabled(False)
520                #self.progressBarEEGLowAlpha.setEnabled(False)
521                #self.progressBarEEGHighAlpha.setEnabled(False)
522                #self.progressBarEEGLowBeta.setEnabled(False)
523                #self.progressBarEEGHighBeta.setEnabled(False)
524                #self.progressBarEEGLowGamma.setEnabled(False)
525                #self.progressBarEEGMidGamma.setEnabled(False)
526               
527                ##self.progressBarAttention.setEnabled(False)
528                ##self.progressBarMeditation.setEnabled(False)
529       
530       
531        ##################################################################
532       
533        #def stopEmotivService(self):
534               
535                ##self.emotivClient.stop()
536               
537                #self.progressBarEEGDelta.setEnabled(True)
538                #self.progressBarEEGTheta.setEnabled(True)
539                #self.progressBarEEGLowAlpha.setEnabled(True)
540                #self.progressBarEEGHighAlpha.setEnabled(True)
541                #self.progressBarEEGLowBeta.setEnabled(True)
542                #self.progressBarEEGHighBeta.setEnabled(True)
543                #self.progressBarEEGLowGamma.setEnabled(True)
544                #self.progressBarEEGMidGamma.setEnabled(True)
545               
546                ##self.progressBarAttention.setEnabled(True)
547                ##self.progressBarMeditation.setEnabled(True)
548       
549       
550        ##################################################################
551       
552        #def updateInterface(self):
553               
554                #if not self.synapseServer.emulate_headset_data:
555                        #self.processPacketThinkGear( \
556                                #self.synapseServer.protocol.data_packet)
557       
558       
559        ##################################################################
560       
561        #def processPacket(self, packet):
562               
563                #self.processPacketThinkGear(packet)
564                #self.processPacketEmotiv(packet)
565               
566               
567                ##if ((self.synapseServer.protocol != None) and
568                #if (self.tabWidget.currentIndex() == \
569                    #self.tabWidget.indexOf(self.tabControlPanel)):
570                       
571                        #self.updateProfileSessionStatus()
572       
573       
574        ##################################################################
575       
576        #def processPacketThinkGear(self, packet):
577               
578                ##if self.DEBUG > 2:
579                        ##print packet
580               
581               
582                #if ('rawEeg' in packet.keys()):
583                        #self.packets['rawEeg'].append(packet['rawEeg'])
584                        #value = packet['rawEeg']
585                        #if MATPLOTLIB_AVAILABLE and \
586                                #(self.tabWidget.currentIndex() == \
587                                 #self.tabWidget.indexOf(self.tabEEGSignals)):
588                                #self.rawEEGMatplot.update_figure(value)
589                        #return
590                #else:
591                        #self.packets['signals'].append(packet)
592               
593               
594                #if ('poorSignalLevel' in packet.keys()):
595                        #value = 200 - packet['poorSignalLevel']
596                        #self.progressBarSignalContactQuality.setValue(value)
597                        #self.textEditDebugConsole.append("")
598                        #try:
599                                #(date, localtime) = self.parseTimeStamp(packet['timestamp'])
600                                #self.textEditDebugConsole.append("Timestamp: %s %s" % (date, localtime))
601                        #except:
602                                #pass
603                        #self.textEditDebugConsole.append("poorSignalLevel: %i" % \
604                                                         #packet['poorSignalLevel'])
605               
606               
607                #if ('eSense' in packet.keys()):
608                       
609                        #if ('attention' in packet['eSense'].keys()):
610                                #value = packet['eSense']['attention']
611                                #self.progressBarAttention.setValue(value)
612                                #self.textEditDebugConsole.append("eSense attention: %i" % value)
613                       
614                        #if ('meditation' in packet['eSense'].keys()):
615                                #value = packet['eSense']['meditation']
616                                #self.progressBarMeditation.setValue(value)
617                                #self.textEditDebugConsole.append("eSense meditation: %i" % value)
618                       
619                       
620                        #if MATPLOTLIB_AVAILABLE:
621                                #self.chartEEGMatplot.update_values('eSense', packet['eSense'])
622                                #if (self.tabWidget.currentIndex() == \
623                                    #self.tabWidget.indexOf(self.tabCharts)):
624                                        #self.chartEEGMatplot.update_figure('eSense', packet['eSense'])
625               
626               
627                #if ('eegPower' in packet.keys()):
628                       
629                        ## If we are not emulating packets we'll set the maximum EEG Power value
630                        ## threshold to the default (or maximum value found within this packet)
631                        #if not self.synapseServer.emulate_headset_data:
632                                #self.maxEEGPower = THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE
633                       
634                        #for value in packet['eegPower'].keys():
635                                #if packet['eegPower'][value] > self.maxEEGPower:
636                                        #self.maxEEGPower = packet['eegPower'][value]
637                       
638                       
639                        #if ('delta' in packet['eegPower'].keys()):
640                                #value = packet['eegPower']['delta']
641                                #self.progressBarEEGDelta.setMaximum(self.maxEEGPower)
642                                #self.progressBarEEGDelta.setValue(value)
643                                #self.textEditDebugConsole.append("delta: %i" % value)
644                       
645                        #if ('theta' in packet['eegPower'].keys()):
646                                #value = packet['eegPower']['theta']
647                                #self.progressBarEEGTheta.setMaximum(self.maxEEGPower)
648                                #self.progressBarEEGTheta.setValue(value)
649                                #self.textEditDebugConsole.append("theta: %i" % value)
650                       
651                        #if ('lowAlpha' in packet['eegPower'].keys()):
652                                #value = packet['eegPower']['lowAlpha']
653                                #self.progressBarEEGLowAlpha.setMaximum(self.maxEEGPower)
654                                #self.progressBarEEGLowAlpha.setValue(value)
655                                #self.textEditDebugConsole.append("lowAlpha: %i" % value)
656                       
657                        #if ('highAlpha' in packet['eegPower'].keys()):
658                                #value = packet['eegPower']['highAlpha']
659                                #self.progressBarEEGHighAlpha.setMaximum(self.maxEEGPower)
660                                #self.progressBarEEGHighAlpha.setValue(value)
661                                #self.textEditDebugConsole.append("highAlpha: %i" % value)
662                       
663                        #if ('lowBeta' in packet['eegPower'].keys()):
664                                #value = packet['eegPower']['lowBeta']
665                                #self.progressBarEEGLowBeta.setMaximum(self.maxEEGPower)
666                                #self.progressBarEEGLowBeta.setValue(value)
667                                #self.textEditDebugConsole.append("lowBeta: %i" % value)
668                       
669                        #if ('highBeta' in packet['eegPower'].keys()):
670                                #value = packet['eegPower']['highBeta']
671                                #self.progressBarEEGHighBeta.setMaximum(self.maxEEGPower)
672                                #self.progressBarEEGHighBeta.setValue(value)
673                                #self.textEditDebugConsole.append("highBeta: %i" % value)
674                       
675                        #if ('lowGamma' in packet['eegPower'].keys()):
676                                #value = packet['eegPower']['lowGamma']
677                                #self.progressBarEEGLowGamma.setMaximum(self.maxEEGPower)
678                                #self.progressBarEEGLowGamma.setValue(value)
679                                #self.textEditDebugConsole.append("lowGamma: %i" % value)
680                       
681                        #if ('highGamma' in packet['eegPower'].keys()):
682                                #value = packet['eegPower']['highGamma']
683                                #self.progressBarEEGMidGamma.setMaximum(self.maxEEGPower)
684                                #self.progressBarEEGMidGamma.setValue(value)
685                                #self.textEditDebugConsole.append("highGamma: %i" % value)
686                       
687                       
688                        #if MATPLOTLIB_AVAILABLE:
689                                #self.chartEEGMatplot.update_values('eegPower', packet['eegPower'])
690                                #if (self.tabWidget.currentIndex() == \
691                                    #self.tabWidget.indexOf(self.tabCharts)):
692                                        #self.chartEEGMatplot.update_figure('eegPower', packet['eegPower'])
693               
694               
695                ###if ((self.synapseServer.protocol != None) and
696                ##if (self.tabWidget.currentIndex() == \
697                    ##self.tabWidget.indexOf(self.tabControlPanel)):
698                       
699                        ##self.updateProfileSessionStatus()
700       
701       
702        ##################################################################
703       
704        #def processPacketEmotiv(self, packet):
705               
706                #if self.DEBUG > 2:
707                        #print "INFO [Synapse:Interface] Emotiv packet received:"
708                        #print packet
709               
710               
711                #if ('emotivStatus' in packet.keys()):
712                       
713                        #if ('timeFromStart' in packet['emotivStatus']):
714                                #if not configuration.EMULATE_THINKGEAR_FOR_EMOTIV:
715                                        #self.textEditDebugConsole.append("")
716                                        #try:
717                                                #(date, localtime) = self.parseTimeStamp(packet['timestamp'])
718                                                #self.textEditDebugConsole.append("Timestamp: %s %s" % (date, localtime))
719                                        #except:
720                                                #pass
721                                #self.textEditDebugConsole.append("timeFromStart: %f" % \
722                                                                  #packet['emotivStatus']['timeFromStart'])
723                       
724                        #if ('headsetOn' in packet['emotivStatus']):
725                                #self.textEditDebugConsole.append("headsetOn: %s" % \
726                                                                  #bool(packet['emotivStatus']['headsetOn']))
727                       
728                        #if ('contactNumberOfQualityChannels' in packet['emotivStatus']):
729                                #self.textEditDebugConsole.append("contactNumberOfQualityChannels: %i" % \
730                                                                  #packet['emotivStatus']['contactNumberOfQualityChannels'])
731                       
732                        #if ('wireless' in packet['emotivStatus']):
733                                #self.textEditDebugConsole.append("wireless: %i" % \
734                                                                  #packet['emotivStatus']['wireless'])
735               
736               
737                #if ('affectiv' in packet.keys()):
738                       
739                        #if ('excitement' in packet['affectiv']):
740                                #self.textEditDebugConsole.append("excitement: %.2f" % \
741                                                                  #packet['affectiv']['excitement'])
742                       
743                        #if ('longTermExcitement' in packet['affectiv']):
744                                #self.textEditDebugConsole.append("longTermExcitement: %.2f" % \
745                                                                  #packet['affectiv']['longTermExcitement'])
746                       
747                        #if ('meditation' in packet['affectiv']):
748                                #self.textEditDebugConsole.append("meditation: %.2f" % \
749                                                                  #packet['affectiv']['meditation'])
750                       
751                        #if ('frustration' in packet['affectiv']):
752                                #self.textEditDebugConsole.append("frustration: %.2f" % \
753                                                                  #packet['affectiv']['frustration'])
754                       
755                        #if ('engagementBoredom' in packet['affectiv']):
756                                #self.textEditDebugConsole.append("engagementBoredom: %.2f" % \
757                                                                  #packet['affectiv']['engagementBoredom'])
758               
759               
760                #if ('cognitiv' in packet.keys()):
761                       
762                        #if ('currentAction' in packet['cognitiv']):
763                                #self.textEditDebugConsole.append("currentAction: %i" % \
764                                                                  #packet['cognitiv']['currentAction'])
765                       
766                        #if ('currentActionPower' in packet['cognitiv']):
767                                #self.textEditDebugConsole.append("currentActionPower: %.2f" % \
768                                                                  #packet['cognitiv']['currentActionPower'])
769       
770       
771        ##################################################################
772       
773        def updateProfileSessionStatus(self, source=None, target=None):
774               
775                session_time = self.calculateSessionTime()
776               
777                if source == None:
778                        if self.parent == None:
779                                source = self
780                        else:
781                                source = self.parent
782               
783                if target == None:
784                        if self.parent == None:
785                                target = self
786                        else:
787                                target = self.parent
788               
789                target.textLabelSessionTime.setText(session_time)
790               
791                try:
792                        target.textLabelPacketsReceived.setText( "%i" % \
793                                source.synapseServer.protocol.packet_count)
794                except:
795                        pass
796               
797                try:
798                        target.textLabelPacketsDropped.setText( "%i" % \
799                                source.synapseServer.protocol.bad_packets)
800                except:
801                        pass
802       
803       
804        ##################################################################
805       
806        def calculateSessionTime(self):
807               
808                if self.parent == None:
809                        server = self.synapseServer
810                else:
811                        server = self.parent.synapseServer
812               
813                session_time = time.time() - \
814                        server.session_start_timestamp
815                        #server.protocol.session_start_timestamp
816               
817                session_time = int(session_time)
818               
819                session_time = self.convert_seconds_to_datetime(session_time)
820               
821                return(session_time)
822       
823       
824        ##################################################################
825       
826        def enumerateSerialPorts(self):
827               
828                """ Uses the Win32 registry to return an
829                iterator of serial (COM) ports
830                existing on this computer.
831               
832                from http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/
833                """
834         
835                path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
836                try:
837                        key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path)
838                except WindowsError:
839                        #raise IterationError
840                        return
841               
842                for i in itertools.count():
843                        try:
844                                val = winreg.EnumValue(key, i)
845                                yield str(val[1])
846                        except EnvironmentError:
847                                break
848       
849       
850        ##################################################################
851       
852        def fullPortName(self, portname):
853               
854                """ Given a port-name (of the form COM7,
855                COM12, CNCA0, etc.) returns a full
856                name suitable for opening with the
857                Serial class.
858                """
859               
860                m = re.match('^COM(\d+)$', portname)
861                if m and int(m.group(1)) < 10:
862                        return portname
863               
864                return '\\\\.\\' + portname
865       
866       
867        ##################################################################
868       
869        def searchForSerialDevices(self, devices=[]):
870               
871                if (sys.platform == 'win32'):
872                       
873                        for portname in self.enumerateSerialPorts():
874                               
875                                if portname not in devices:
876                                        #portname = self.fullPortName(portname)
877                                        devices.append(portname)
878               
879                else:
880                       
881                       
882                        if os.path.exists('/dev/tty.MindWaveMobile-SPPDev'):
883                                devices.append('/dev/tty.MindWaveMobile-SPPDev')
884                       
885                        if os.path.exists('/dev/tty.MindWave'):
886                                devices.append('/dev/tty.MindWave')
887                        if os.path.exists('/dev/tty.MindWave1'):
888                                devices.append('/dev/tty.MindWave1')
889                        if os.path.exists('/dev/tty.MindWave2'):
890                                devices.append('/dev/tty.MindWave2')
891                        if os.path.exists('/dev/tty.MindWave3'):
892                                devices.append('/dev/tty.MindWave3')
893                        if os.path.exists('/dev/tty.MindWave4'):
894                                devices.append('/dev/tty.MindWave4')
895                        if os.path.exists('/dev/tty.MindWave5'):
896                                devices.append('/dev/tty.MindWave5')
897                       
898                        if os.path.exists('/dev/tty.MindSet-DevB'):
899                                devices.append('/dev/tty.MindSet-DevB')
900                       
901                        if os.path.exists('/dev/ttyUSB0'):
902                                devices.append('/dev/ttyUSB0')
903                        if os.path.exists('/dev/ttyUSB1'):
904                                devices.append('/dev/ttyUSB1')
905                        if os.path.exists('/dev/ttyUSB2'):
906                                devices.append('/dev/ttyUSB2')
907                        if os.path.exists('/dev/ttyUSB3'):
908                                devices.append('/dev/ttyUSB3')
909                        if os.path.exists('/dev/ttyUSB4'):
910                                devices.append('/dev/ttyUSB4')
911                        if os.path.exists('/dev/ttyUSB5'):
912                                devices.append('/dev/ttyUSB5')
913                        if os.path.exists('/dev/ttyUSB6'):
914                                devices.append('/dev/ttyUSB6')
915                        if os.path.exists('/dev/ttyUSB7'):
916                                devices.append('/dev/ttyUSB7')
917                        if os.path.exists('/dev/ttyUSB8'):
918                                devices.append('/dev/ttyUSB8')
919                        if os.path.exists('/dev/ttyUSB9'):
920                                devices.append('/dev/ttyUSB9')
921                       
922                        if os.path.exists('/dev/rfcomm0'):
923                                devices.append('/dev/rfcomm0')
924                        if os.path.exists('/dev/rfcomm1'):
925                                devices.append('/dev/rfcomm1')
926                        if os.path.exists('/dev/rfcomm2'):
927                                devices.append('/dev/rfcomm2')
928                        if os.path.exists('/dev/rfcomm3'):
929                                devices.append('/dev/rfcomm3')
930                        if os.path.exists('/dev/rfcomm4'):
931                                devices.append('/dev/rfcomm4')
932                       
933                        if os.path.exists('/dev/ttyACM0'):
934                                devices.append('/dev/ttyACM0')
935                        if os.path.exists('/dev/ttyACM1'):
936                                devices.append('/dev/ttyACM1')
937                        if os.path.exists('/dev/ttyACM2'):
938                                devices.append('/dev/ttyACM2')
939                        if os.path.exists('/dev/ttyACM3'):
940                                devices.append('/dev/ttyACM3')
941                        if os.path.exists('/dev/ttyACM4'):
942                                devices.append('/dev/ttyACM4')
943               
944               
945                return(devices)
946       
947       
948        ##################################################################
949       
950        def hcitoolScanForRemoteDevices(self, devices=[]):
951               
952                bluetooth_devices = []
953               
954                #command = '%s scan 2> /dev/null' % PATH_TO_HCITOOL
955                command = '%s scan' % PATH_TO_HCITOOL
956               
957                if self.DEBUG > 1:
958                        print 'INFO: Calling "%s"' % command
959               
960                output = os.popen(command, 'r')
961               
962                try:
963                        result = output.readlines()
964                except Exception, e:
965                        if self.DEBUG:
966                                print "ERROR [Synapse-Interface]: Failed reading result from call to hcitool:",
967                                print e
968                        result = ''
969               
970                if result == '':
971                        return([]) # Under OS X hcitool doesn't exist so we don't see any devices
972               
973                for line in result:
974                        line = line.strip()
975                        if line == '' or line == 'Scanning ...':
976                                continue
977                        elif self.DEBUG > 1:
978                                print line
979                        try:
980                                address = line.split('\t')[0]
981                        except:
982                                pass
983                        else:
984                                bluetooth_devices.append(address)
985               
986               
987                for address in bluetooth_devices:
988                       
989                        command = '%s name %s' % (PATH_TO_HCITOOL, address)
990                       
991                        if self.DEBUG:
992                                print 'INFO: Calling "%s"' % command
993                       
994                        output = os.popen(command, 'r')
995                       
996                        for line in output.readlines():
997                                line = line.strip()
998                                if line == '':
999                                        continue
1000                                elif self.DEBUG:
1001                                        print '\t',
1002                                        print line
1003                               
1004                                device_name = line.strip()
1005                       
1006                                if ((device_name == 'MindSet' or device_name == 'MindWave Mobile') and \
1007                                        (address not in devices)):
1008                                        devices.append(address)
1009                               
1010                                else:
1011                                        if self.DEBUG:
1012                                                print 'INFO: Found but not recognized: [%s] %s' % \
1013                                                        (address, device_name)
1014               
1015               
1016                return (devices)
1017       
1018       
1019        ##################################################################
1020       
1021        def hcitoolGetActiveConnections(self, devices=[]):
1022               
1023                bluetooth_devices = []
1024               
1025                #command = '%s con 2> /dev/null' % PATH_TO_HCITOOL
1026                command = '%s con' % PATH_TO_HCITOOL
1027               
1028                if self.DEBUG > 1:
1029                        print 'INFO: Calling "%s"' % command
1030               
1031                output = os.popen(command, 'r')
1032               
1033                try:
1034                        result = output.readlines()
1035                except Exception, e:
1036                        if self.DEBUG:
1037                                print "ERROR [Synapse:Interface]: Failed reading result from call to hcitool:",
1038                                print e
1039                        result = ''
1040
1041                if result == '':
1042                        return([]) # Under OS X hcitool doesn't exist so we don't see any devices
1043
1044                for line in result:
1045                        line = line.strip()
1046                        if line == '' or line == 'Connections:':
1047                                continue
1048                        elif self.DEBUG > 1:
1049                                print line
1050                        try:
1051                                address = line.split(' ')[2]
1052                        except:
1053                                pass
1054                        else:
1055                                bluetooth_devices.append(address)
1056               
1057               
1058                for address in bluetooth_devices:
1059                       
1060                        command = '%s name %s' % (PATH_TO_HCITOOL, address)
1061                       
1062                        if self.DEBUG:
1063                                print 'INFO: Calling "%s":' % command
1064                       
1065                        output = os.popen(command, 'r')
1066                       
1067                        for line in output.readlines():
1068                                line = line.strip()
1069                                if line == '':
1070                                        continue
1071                                elif self.DEBUG:
1072                                        print '\t',
1073                                        print line
1074                               
1075                                device_name = line.strip()
1076                       
1077                                if ((device_name == 'MindSet' or device_name == 'MindWave Mobile') and \
1078                                        (address not in devices)):
1079                                        devices.append(address)
1080               
1081               
1082                return (devices)
1083       
1084       
1085        ##################################################################
1086       
1087        def searchForDevices(self):
1088               
1089                enable_hcitool = configuration.ENABLE_HCITOOL
1090               
1091                devices = []
1092               
1093                #self.pushButtonBluetoothSearch.setText('Searching')
1094               
1095                if ((sys.platform != 'win32' and sys.platform != 'darwin') and \
1096                     configuration.THINKGEAR_BLUETOOTH_SEARCH):
1097                       
1098                        # Bluetooth module doesn't compile properly under Windows
1099                        # and doesn't exist under OS X
1100                       
1101                        # PyBluez API Documentation
1102                        # http://pybluez.googlecode.com/svn/www/docs-0.7/index.html
1103                       
1104                        bluetooth_devices = []
1105                       
1106                        if not enable_hcitool:
1107                               
1108                                try:
1109                                       
1110                                        if self.DEBUG:
1111                                                print "INFO: Searching for Bluetooth devices using PyBluez module"
1112                                       
1113                                        bluetooth_devices = bluetooth.discover_devices( \
1114                                              duration=configuration.THINKGEAR_BLUETOOTH_DISCOVER_DEVICES_TIMEOUT, \
1115                                                               flush_cache=True, \
1116                                                               lookup_names=False)
1117                                       
1118                                        for address in bluetooth_devices:
1119                                               
1120                                                if self.DEBUG:
1121                                                        print "INFO: Device discovered",
1122                                                        print address
1123                                               
1124                                                device_name = bluetooth.lookup_name(address, \
1125                                                                 configuration.THINKGEAR_BLUETOOTH_LOOKUP_NAME_TIMEOUT)
1126                                                if ((device_name == 'MindSet' or device_name == 'MindWave Mobile') and \
1127                                                        (address not in devices)):
1128                                                        devices.append(address)
1129                                       
1130                                       
1131                                        # There is an issue under recent released of Linux
1132                                        # in which already-connected Bluetooth ThinkGear devices
1133                                        # are not appearing in a bluetooth device scan. However,
1134                                        # using "hcitool" connected devices can be listed correctly.
1135                                        # There does not appear to be an equivalent PyBluez feature.
1136                                        # (http://pybluez.googlecode.com/svn/www/docs-0.7/index.html)
1137                                       
1138                                        if devices == []:
1139                                                if self.DEBUG:
1140                                                        print "INFO: No devices found through PyBluez module. Falling back to hcitool."
1141                                                devices = self.hcitoolGetActiveConnections(devices)
1142                               
1143                               
1144                                except Exception, e:
1145                                        if self.DEBUG:
1146                                                print "ERROR: Exception calling Python Bluetooth module. (Is PyBluez installed?):"
1147                                                print e
1148                                       
1149                                       
1150                                        #if (sys.platform != 'darwin'):
1151                                        enable_hcitool = True
1152                       
1153                       
1154                        if enable_hcitool:
1155                               
1156                                devices = self.hcitoolScanForRemoteDevices(devices)
1157                                devices = self.hcitoolGetActiveConnections(devices)
1158                       
1159                       
1160                        if self.DEBUG > 2:
1161                                print "Bluetooth Devices found:",
1162                                print devices
1163               
1164               
1165                devices = self.searchForSerialDevices(devices)
1166               
1167               
1168                if self.DEBUG:
1169                        print "Devices found:",
1170                        print devices
1171               
1172               
1173                return(devices)
1174       
1175       
1176        ##################################################################
1177       
1178        #def updateDevices(self):
1179               
1180                #if (self.parent != None):
1181                        #source = self.parent
1182                #else:
1183                        #source = self
1184               
1185                #model = source.comboBoxEEGHeadsetModel.currentText()
1186               
1187                #devices = self.searchForDevices()
1188               
1189                #source.comboBoxDeviceSelect.clear()
1190               
1191                #if (model == 'NeuroSky MindWave' or \
1192                    #model == 'NeuroSky MindSet' or \
1193                    #model == 'NeuroSky MindWave Mobile'):
1194                       
1195                        #devices.insert(0, 'ThinkGear Emulator')
1196               
1197                #elif (model == 'Emotiv EPOC'):
1198                       
1199                        #devices.insert(0, 'EmoComposer')
1200                        #devices.insert(0, 'Emotiv Control Panel')
1201               
1202               
1203                #for device in devices:
1204                        #source.comboBoxDeviceSelect.addItem(device)
1205       
1206       
1207        ##################################################################
1208       
1209        def collectData(self, source=None, target=None):
1210               
1211                if source == None:
1212                        if self.parent == None:
1213                                source = self
1214                        else:
1215                                source = self.parent
1216               
1217                if target == None:
1218                        if self.parent == None:
1219                                target = self
1220                        else:
1221                                target = self.parent
1222               
1223                data = {}
1224               
1225                data['rawEeg'] = source.packets['rawEeg']
1226                data['signals'] = source.packets['signals']
1227               
1228                data['sessionTime'] = self.calculateSessionTime()
1229               
1230                data['profileName'] = str(target.lineEditSessionProfile.text())
1231               
1232                return(data)
1233       
1234       
1235        ##################################################################
1236       
1237        def parseTimeStamp(self, timestamp, local_version=False, truncate_time_zone=False):
1238               
1239                try:
1240                        decimal = '%f' % timestamp
1241                        decimal = decimal.split('.')[1]
1242                except:
1243                        decimal = '0'
1244               
1245                localtime = time.localtime(timestamp)
1246               
1247                if local_version:
1248                        date = time.strftime('%x', localtime)
1249                        localtime = time.strftime('%X', localtime)
1250               
1251                elif truncate_time_zone:
1252                        date = time.strftime('%Y-%m-%d', localtime)
1253                        localtime = time.strftime('%H:%M:%S', localtime)
1254                        localtime = '%s.%s' % (localtime, decimal[:3])
1255               
1256                else:
1257                        date = time.strftime('%Y-%m-%d', localtime)
1258                        localtime = time.strftime('%H:%M:%S', localtime)
1259                        localtime = '%s.%s %s' % (localtime, decimal, \
1260                                       time.strftime('%Z', time.localtime(timestamp)))
1261               
1262               
1263                return(date, localtime)
1264       
1265       
1266        ##################################################################
1267       
1268        def saveData(self, source=None, target=None, output_file=None, use_default=False):
1269               
1270                if source == None:
1271                        if self.parent == None:
1272                                source = self
1273                        else:
1274                                source = self.parent
1275               
1276                if target == None:
1277                        if self.parent == None:
1278                                target = self
1279                        else:
1280                                target = self.parent
1281               
1282                data = self.collectData(source=source, target=target)
1283               
1284                (date, localtime) = self.parseTimeStamp(time.time())
1285               
1286                default_filename = '%s %s.synapse' % (date, \
1287                                      target.lineEditSessionProfile.text())
1288                                     
1289                default_filename = os.path.join(self.homepath, default_filename)
1290               
1291                if output_file == None:
1292                       
1293                        # use_default controls whether or not a file is automatically saves using the
1294                        # default name and path (as opposed to raising a GUI file selection menu)
1295                        # whenever an explicit filepath is not defined
1296                        if use_default:
1297                                       
1298                                        output_file = default_filename
1299                       
1300                        else:
1301                       
1302                                output_file = QtGui.QFileDialog.getSaveFileName(parent=target, \
1303                                                 caption="Save Session Data to File", \
1304                                                 dir=default_filename, \
1305                                                 filter="Puzzlebox Synapse Data File (*.synapse)")
1306                               
1307                                try:
1308                                        output_file = output_file[0]
1309                                except:
1310                                        output_file = ''
1311               
1312               
1313                if output_file == '':
1314                        return
1315               
1316                file = open(str(output_file), 'w')
1317                pickle.dump(data, file)
1318                file.close()
1319       
1320       
1321        ##################################################################
1322       
1323        def exportData(self, parent=None, source=None, target=None, output_file=None, use_default=False):
1324               
1325                if parent == None:
1326                        if self.parent == None:
1327                                parent = self
1328                        else:
1329                                parent = self.parent
1330               
1331                if source == None:
1332                        if self.parent == None:
1333                                source = self
1334                        else:
1335                                source = self.parent
1336               
1337                if target == None:
1338                        if self.parent == None:
1339                                target = self
1340                        else:
1341                                target = self.parent
1342               
1343               
1344                (date, localtime) = self.parseTimeStamp(time.time())
1345               
1346                default_filename = '%s %s.csv' % (date, \
1347                                      target.lineEditSessionProfile.text())
1348               
1349                default_filename = os.path.join(target.homepath, default_filename)
1350               
1351               
1352                if output_file == None:
1353                       
1354                        # use_default controls whether or not a file is automatically saves using the
1355                        # default name and path (as opposed to raising a GUI file selection menu)
1356                        # whenever an explicit filepath is not defined
1357                        if use_default:
1358                                       
1359                                        output_file = default_filename
1360                       
1361                        else:
1362                                output_file = QtGui.QFileDialog.getSaveFileName(parent=target, \
1363                                                 caption="Export Session Data to File", \
1364                                                 dir=default_filename, \
1365                                                 filter="CSV File (*.csv);;Text File (*.txt)")
1366                               
1367                                try:
1368                                        output_file = output_file[0]
1369                                except:
1370                                        output_file = ''
1371               
1372               
1373                if output_file == '':
1374                        return
1375               
1376               
1377                if str(output_file).endswith('.csv'):
1378                       
1379                        outputData = self.exportDataToCSV(parent=parent, source=source, target=target)
1380               
1381               
1382                else:
1383                       
1384                        try:
1385                                outputData = self.textEditDebugConsole.toPlainText()
1386                        except:
1387                                outputData = self.exportDataToCSV()
1388               
1389               
1390                file = open(str(output_file), 'w')
1391                file.write(outputData)
1392                file.close()
1393       
1394       
1395        ##################################################################
1396       
1397        def exportDataToCSV(self, parent=None, source=None, target=None):
1398               
1399                if parent == None:
1400                        if self.parent == None:
1401                                parent = self
1402                        else:
1403                                parent = self.parent
1404               
1405                if source == None:
1406                        if self.parent == None:
1407                                source = self
1408                        else:
1409                                source = self.parent
1410               
1411                if target == None:
1412                        if self.parent == None:
1413                                target = self
1414                        else:
1415                                target = self.parent
1416               
1417                try:
1418                        truncate_csv_timezone = target.configuration.EXPORT_CSV_TRUNCATE_TIMEZONE
1419                except:
1420                        truncate_csv_timezone = False
1421               
1422                try:
1423                        scrub_data = target.configuration.EXPORT_CSV_SCRUB_DATA
1424                except:
1425                        scrub_data = False
1426               
1427               
1428                headers = 'Date,Time,Attention,Meditation,Signal Level,Delta,Theta,Low Alpha,High Alpha,Low Beta,High Beta,Low Gamma,Mid Gamma'
1429               
1430                customDataHeaders = []
1431                for header in parent.customDataHeaders:
1432                        customDataHeaders.append(header)
1433                for plugin in parent.activePlugins:
1434                        for header in plugin.customDataHeaders:
1435                                customDataHeaders.append(header)
1436               
1437                for each in customDataHeaders:
1438                        headers = headers + ',%s' % each
1439               
1440                headers = headers + '\n'
1441               
1442                csv = {}
1443               
1444                for packet in source.packets['signals']:
1445                       
1446                       
1447                        if 'rawEeg' in packet.keys():
1448                                continue
1449                       
1450                        if packet['timestamp'] not in csv.keys():
1451                               
1452                                if 'blinkStrength' in packet.keys():
1453                                        # Skip any blink packets from log
1454                                        continue
1455                               
1456                               
1457                                #print packet
1458                                timestamp = packet['timestamp']
1459                                (date, localtime) = self.parseTimeStamp(timestamp, \
1460                                                    truncate_time_zone=truncate_csv_timezone)
1461                               
1462                                csv[timestamp] = {}
1463                                csv[timestamp]['Date'] = date
1464                                csv[timestamp]['Time'] = localtime
1465                                csv[timestamp]['Attention'] = ''
1466                                csv[timestamp]['Meditation'] = ''
1467                                csv[timestamp]['Signal Level'] = ''
1468                                csv[timestamp]['Delta'] = ''
1469                                csv[timestamp]['Theta'] = ''
1470                                csv[timestamp]['Low Alpha'] = ''
1471                                csv[timestamp]['High Alpha'] = ''
1472                                csv[timestamp]['Low Beta'] = ''
1473                                csv[timestamp]['High Beta'] = ''
1474                                csv[timestamp]['Low Gamma'] = ''
1475                                csv[timestamp]['Mid Gamma'] = ''
1476                               
1477                                for header in customDataHeaders:
1478                                        csv[timestamp][header] = ''
1479                       
1480                       
1481                        if 'eSense' in packet.keys():
1482                                if 'attention' in packet['eSense'].keys():
1483                                        csv[timestamp]['Attention'] = packet['eSense']['attention']
1484                                if 'meditation' in packet['eSense'].keys():
1485                                        csv[timestamp]['Meditation'] = packet['eSense']['meditation']
1486                       
1487                        if 'eegPower' in packet.keys():
1488                                if 'delta' in packet['eegPower'].keys():
1489                                        csv[timestamp]['Delta'] = packet['eegPower']['delta']
1490                                if 'theta' in packet['eegPower'].keys():
1491                                        csv[timestamp]['Theta'] = packet['eegPower']['theta']
1492                                if 'lowAlpha' in packet['eegPower'].keys():
1493                                        csv[timestamp]['Low Alpha'] = packet['eegPower']['lowAlpha']
1494                                if 'highAlpha' in packet['eegPower'].keys():
1495                                        csv[timestamp]['High Alpha'] = packet['eegPower']['highAlpha']
1496                                if 'lowBeta' in packet['eegPower'].keys():
1497                                        csv[timestamp]['Low Beta'] = packet['eegPower']['lowBeta']
1498                                if 'highBeta' in packet['eegPower'].keys():
1499                                        csv[timestamp]['High Beta'] = packet['eegPower']['highBeta']
1500                                if 'lowGamma' in packet['eegPower'].keys():
1501                                        csv[timestamp]['Low Gamma'] = packet['eegPower']['lowGamma']
1502                                if 'highGamma' in packet['eegPower'].keys():
1503                                        csv[timestamp]['Mid Gamma'] = packet['eegPower']['highGamma']
1504                       
1505                        if 'poorSignalLevel' in packet.keys():
1506                                csv[timestamp]['Signal Level'] = packet['poorSignalLevel']
1507                       
1508                        for header in customDataHeaders:
1509                                if 'custom' in packet.keys() and \
1510                                   header in packet['custom'].keys():
1511                                        csv[timestamp][header] = packet['custom'][header]
1512               
1513               
1514                if scrub_data:
1515                        csv = self.scrubData(csv, truncate_csv_timezone)
1516               
1517               
1518                output = headers
1519               
1520                csv_keys = csv.keys()
1521                csv_keys.sort()
1522               
1523                for key in csv_keys:
1524                       
1525                        row = '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s' % \
1526                              (csv[key]['Date'], \
1527                               csv[key]['Time'], \
1528                               csv[key]['Attention'], \
1529                               csv[key]['Meditation'], \
1530                               csv[key]['Signal Level'], \
1531                               csv[key]['Delta'], \
1532                               csv[key]['Theta'], \
1533                               csv[key]['Low Alpha'], \
1534                               csv[key]['High Alpha'], \
1535                               csv[key]['Low Beta'], \
1536                               csv[key]['High Beta'], \
1537                               csv[key]['Low Gamma'], \
1538                               csv[key]['Mid Gamma'])
1539                       
1540                        for header in customDataHeaders:
1541                                row = row + ',%s' % csv[key][header]
1542                       
1543                        row = row + '\n'
1544                       
1545                        output = output + row
1546               
1547               
1548                return(output)
1549       
1550       
1551        ##################################################################
1552       
1553        def scrubData(self, csv, truncate_csv_timezone=False):
1554               
1555                # If there are missing packets, repeat a given packet once per missing
1556                # second until there is a gap between 1 and 2 seconds, in which case
1557                # produce a final duplicate packet at the mid-point between the packets
1558
1559                if self.DEBUG:
1560                        print "INFO: Scrubbing Data"
1561               
1562                last_time = None
1563                last_recorded_time = None
1564               
1565                output = {}
1566               
1567                csv_keys = csv.keys()
1568                csv_keys.sort()
1569               
1570                for key in csv_keys:
1571                       
1572                        timestamp = key
1573
1574                        if csv[key]['Attention'] == '':
1575                                continue
1576                       
1577                        if last_time == None:
1578                                # First entry in log
1579                                last_time = timestamp
1580                                last_recorded_time = timestamp
1581                                output[key] = csv[key]
1582                                continue
1583                       
1584                        else:
1585                               
1586                                #time_difference = timestamp - last_time
1587                                time_difference = timestamp - last_recorded_time
1588                               
1589                                if (time_difference <= 1) and \
1590                                   (time_difference >= PACKET_MINIMUM_TIME_DIFFERENCE_THRESHOLD):
1591                                        # Skip packets within the correct time threshold
1592                                        last_time = timestamp
1593                                        last_recorded_time = timestamp
1594                                        output[key] = csv[key]
1595                                        continue
1596                               
1597                                else:
1598                                       
1599                                        if self.DEBUG > 1:
1600                                                print "time_difference:",
1601                                                print time_difference
1602                                                print "timestamp:",
1603                                                print self.parseTimeStamp(timestamp)[-1].split(' ')[0]
1604                                                print "last_time:",
1605                                                print self.parseTimeStamp(last_time)[-1].split(' ')[0]
1606                                                print "last_recorded_time:",
1607                                                print self.parseTimeStamp(last_recorded_time)[-1].split(' ')[0]
1608                                       
1609                                       
1610                                        new_packet = csv[key].copy()
1611                                       
1612                                        if time_difference >= 2:
1613                                               
1614                                                ##new_time = last_time + 1
1615                                                #new_time = last_recorded_time + 1
1616                                               
1617                                                count = int(time_difference)
1618                                                while count >= 1:
1619                                                        new_packet = csv[key].copy()
1620                                                        new_time = last_recorded_time + 1
1621                                                        (date, formatted_new_time) = self.parseTimeStamp(new_time, \
1622                                                         truncate_time_zone=truncate_csv_timezone)
1623                                                        new_packet['Time'] = formatted_new_time
1624                                                        last_recorded_time = new_time
1625                                                        last_time = timestamp
1626                                                        output[new_time] = new_packet
1627                                                        count = count - 1
1628                                                continue
1629                                               
1630                                        elif time_difference < PACKET_MINIMUM_TIME_DIFFERENCE_THRESHOLD:
1631                                                # Spread out "bunched up" packets
1632                                                #new_time = last_time + 1
1633                                                new_time = last_recorded_time + 1
1634                                       
1635                                       
1636                                        elif (time_difference < 2) and (time_difference > 1):
1637                                               
1638                                                #new_time = last_time + ((last_time - timestamp) / 2)
1639                                                #new_time = last_recorded_time + ((last_recorded_time - timestamp) / 2)
1640                                                #new_time = last_time + 1
1641                                                new_time = last_recorded_time + 1
1642                                       
1643                                       
1644                                        (date, formatted_new_time) = self.parseTimeStamp(new_time, \
1645                                           truncate_time_zone=truncate_csv_timezone)
1646                                       
1647                                        new_packet['Time'] = formatted_new_time
1648                                       
1649                                        #last_time = new_time
1650                                        last_recorded_time = new_time
1651                                        last_time = timestamp
1652                                        output[new_time] = new_packet
1653                                       
1654                                        if self.DEBUG > 1:
1655                                                print "WARN: Scrubbing new packet:",
1656                                                print new_packet
1657                                                print
1658               
1659               
1660                return(output)
1661       
1662       
1663        ##################################################################
1664       
1665        def resetData(self, source=None):
1666               
1667                if source == None:
1668                        if self.parent == None:
1669                                source = self
1670                        else:
1671                                source = self.parent
1672               
1673                #if target == None:
1674                        #if self.parent == None:
1675                                #target = self
1676                        #else:
1677                                #target = self.parent
1678               
1679                source.packets['rawEeg'] = []
1680                source.packets['signals'] = []
1681               
1682                source.synapseServer.protocol.session_start_timestamp = \
1683                        time.time()
1684               
1685                source.synapseServer.protocol.packet_count = 0
1686                source.synapseServer.protocol.bad_packets = 0
1687               
1688                self.updateProfileSessionStatus()
1689               
1690                try:
1691                        source.textEditDebugConsole.setText("")
1692                except:
1693                        pass
1694       
1695       
1696        #####################################################################
1697       
1698        def convert_seconds_to_datetime(self, duration):
1699               
1700                duration_hours = duration / (60 * 60)
1701                duration_minutes = (duration - (duration_hours * (60 * 60))) / 60
1702                duration_seconds = (duration - (duration_hours * (60 * 60)) - (duration_minutes * 60))
1703               
1704                duration_hours = '%i' % duration_hours
1705                if (len(duration_hours) == 1):
1706                        duration_hours = "0%s" % duration_hours
1707               
1708                duration_minutes = '%i' % duration_minutes
1709                if (len(duration_minutes) == 1):
1710                        duration_minutes = "0%s" % duration_minutes
1711               
1712                duration_seconds = '%i' % duration_seconds
1713                if (len(duration_seconds) == 1):
1714                        duration_seconds = "0%s" % duration_seconds
1715               
1716                datetime = '%s:%s:%s' % (duration_hours, duration_minutes, duration_seconds)
1717               
1718                return(datetime)
1719       
1720       
1721        ##################################################################
1722       
1723        def stop(self):
1724               
1725                if UPDATE_INTERFACE_VIA_TIMER:
1726                        self.updateInterfaceTimer.stop()
1727                else:
1728                        #if self.thinkgearConnectClient != None:
1729                                #self.thinkgearConnectClient.exitThread()
1730                        #if self.emotivClient != None:
1731                                #self.emotivClient.exitThread()
1732                        if self.synapseClient != None:
1733                                self.synapseClient.exitThread()
1734               
1735                if self.synapseServer != None:
1736                        self.synapseServer.exitThread()
1737       
1738       
1739        ##################################################################
1740       
1741        def closeEvent(self, event):
1742               
1743                quit_message = "Are you sure you want to exit the program?"
1744               
1745                reply = QtGui.QMessageBox.question( \
1746                           self, \
1747                          'Message', \
1748                           quit_message, \
1749                           QtGui.QMessageBox.Yes, \
1750                           QtGui.QMessageBox.No)
1751               
1752                if reply == QtGui.QMessageBox.Yes:
1753                       
1754                        self.stop()
1755                       
1756                        event.accept()
1757               
1758                else:
1759                        event.ignore()
Note: See TracBrowser for help on using the repository browser.