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

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

Device:

  • breakout from Session
File size: 26.4 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"""
14
15### IMPORTS ###
16import os, sys, time
17
18import Puzzlebox.Synapse.Configuration as configuration
19
20if configuration.ENABLE_PYSIDE:
21        try:
22                import PySide as PyQt4
23                from PySide import QtCore, QtGui, QtNetwork
24        except Exception, e:
25                print "ERROR: Exception importing PySide:",
26                print e
27                configuration.ENABLE_PYSIDE = False
28        else:
29                print "INFO: [Synapse:Session] Using PySide module"
30
31if not configuration.ENABLE_PYSIDE:
32        print "INFO: [Synapse:Session] Using PyQt4 module"
33        from PyQt4 import QtCore, QtGui, QtNetwork
34
35
36try:
37        import cPickle as pickle
38except:
39        import pickle
40
41
42#####################################################################
43# Globals
44#####################################################################
45
46DEBUG = configuration.DEBUG
47
48#SYNAPSE_SERVER_HOST = configuration.SYNAPSE_SERVER_HOST
49#SYNAPSE_SERVER_PORT = configuration.SYNAPSE_SERVER_PORT
50
51#EMULATE_THINKGEAR_FOR_EMOTIV = configuration.EMULATE_THINKGEAR_FOR_EMOTIV
52
53PATH_TO_HCITOOL = '/usr/bin/hcitool'
54
55
56#####################################################################
57# Classes
58#####################################################################
59
60class puzzlebox_synapse_session(QtGui.QWidget):
61       
62        def __init__(self, log, \
63                     DEBUG=DEBUG, \
64                     parent=None, \
65                     #embedded_mode=False):
66                     ):
67               
68                self.log = log
69                self.DEBUG = DEBUG
70                self.parent=parent
71                #self.embedded_mode=embedded_mode
72               
73                if self.parent == None:
74                        QtGui.QWidget.__init__(self, parent)
75                        #self.setupUi(self)
76               
77                        self.configureSettings()
78                        self.connectWidgets()
79               
80                self.name = "Synapse:Session"
81               
82               
83                if (sys.platform == 'win32'):
84                        self.homepath = os.path.join( \
85                           os.environ['HOMEDRIVE'], \
86                           os.environ['HOMEPATH'], \
87                           'Desktop')
88                elif (sys.platform == 'darwin'):
89                        desktop = os.path.join(os.environ['HOME'], 'Documents')
90                        if os.path.exists(desktop):
91                                self.homepath = desktop
92                        else:
93                                self.homepath = os.environ['HOME']
94                else:
95                        desktop = os.path.join(os.environ['HOME'], 'Desktop')
96                        if os.path.exists(desktop):
97                                self.homepath = desktop
98                        else:
99                                self.homepath = os.environ['HOME']
100               
101               
102                if not os.path.exists(self.homepath):
103                        if self.DEBUG:
104                                print "DEBUG: User default path not found"
105                        self.homepath = os.getcwd()
106               
107               
108                self.activePlugins = []
109       
110       
111        ##################################################################
112       
113        def configureSettings(self):
114               
115                pass
116       
117       
118        ##################################################################
119       
120        def connectWidgets(self):
121               
122                pass
123       
124       
125        ##################################################################
126       
127        def updateProfileSessionStatus(self, source=None, target=None):
128               
129                session_time = self.calculateSessionTime()
130               
131                if source == None:
132                        if self.parent == None:
133                                source = self
134                        else:
135                                source = self.parent
136               
137                if target == None:
138                        if self.parent == None:
139                                target = self
140                        else:
141                                target = self.parent
142               
143                target.textLabelSessionTime.setText(session_time)
144               
145                try:
146                        target.textLabelPacketsReceived.setText( "%i" % \
147                                source.synapseServer.protocol.packet_count)
148                except:
149                        pass
150               
151                try:
152                        target.textLabelPacketsDropped.setText( "%i" % \
153                                source.synapseServer.protocol.bad_packets)
154                except:
155                        pass
156       
157       
158        ##################################################################
159       
160        def calculateSessionTime(self):
161               
162                if self.parent == None:
163                        server = self.synapseServer
164                else:
165                        server = self.parent.synapseServer
166               
167                session_time = time.time() - \
168                        server.session_start_timestamp
169                        #server.protocol.session_start_timestamp
170               
171                session_time = int(session_time)
172               
173                session_time = self.convert_seconds_to_datetime(session_time)
174               
175                return(session_time)
176       
177       
178        ##################################################################
179       
180        #def enumerateSerialPorts(self):
181               
182                #""" Uses the Win32 registry to return an
183                #iterator of serial (COM) ports
184                #existing on this computer.
185               
186                #from http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/
187                #"""
188         
189                #path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
190                #try:
191                        #key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path)
192                #except WindowsError:
193                        ##raise IterationError
194                        #return
195               
196                #for i in itertools.count():
197                        #try:
198                                #val = winreg.EnumValue(key, i)
199                                #yield str(val[1])
200                        #except EnvironmentError:
201                                #break
202       
203       
204        ##################################################################
205       
206        #def fullPortName(self, portname):
207               
208                #""" Given a port-name (of the form COM7,
209                #COM12, CNCA0, etc.) returns a full
210                #name suitable for opening with the
211                #Serial class.
212                #"""
213               
214                #m = re.match('^COM(\d+)$', portname)
215                #if m and int(m.group(1)) < 10:
216                        #return portname
217               
218                #return '\\\\.\\' + portname
219       
220       
221        ##################################################################
222       
223        #def searchForSerialDevices(self, devices=[]):
224               
225                #if (sys.platform == 'win32'):
226                       
227                        #for portname in self.enumerateSerialPorts():
228                               
229                                #if portname not in devices:
230                                        ##portname = self.fullPortName(portname)
231                                        #devices.append(portname)
232               
233                #else:
234                       
235                       
236                        #if os.path.exists('/dev/tty.MindWaveMobile-SPPDev'):
237                                #devices.append('/dev/tty.MindWaveMobile-SPPDev')
238                       
239                        #if os.path.exists('/dev/tty.MindWave'):
240                                #devices.append('/dev/tty.MindWave')
241                        #if os.path.exists('/dev/tty.MindWave1'):
242                                #devices.append('/dev/tty.MindWave1')
243                        #if os.path.exists('/dev/tty.MindWave2'):
244                                #devices.append('/dev/tty.MindWave2')
245                        #if os.path.exists('/dev/tty.MindWave3'):
246                                #devices.append('/dev/tty.MindWave3')
247                        #if os.path.exists('/dev/tty.MindWave4'):
248                                #devices.append('/dev/tty.MindWave4')
249                        #if os.path.exists('/dev/tty.MindWave5'):
250                                #devices.append('/dev/tty.MindWave5')
251                       
252                        #if os.path.exists('/dev/tty.MindSet-DevB'):
253                                #devices.append('/dev/tty.MindSet-DevB')
254                       
255                        #if os.path.exists('/dev/ttyUSB0'):
256                                #devices.append('/dev/ttyUSB0')
257                        #if os.path.exists('/dev/ttyUSB1'):
258                                #devices.append('/dev/ttyUSB1')
259                        #if os.path.exists('/dev/ttyUSB2'):
260                                #devices.append('/dev/ttyUSB2')
261                        #if os.path.exists('/dev/ttyUSB3'):
262                                #devices.append('/dev/ttyUSB3')
263                        #if os.path.exists('/dev/ttyUSB4'):
264                                #devices.append('/dev/ttyUSB4')
265                        #if os.path.exists('/dev/ttyUSB5'):
266                                #devices.append('/dev/ttyUSB5')
267                        #if os.path.exists('/dev/ttyUSB6'):
268                                #devices.append('/dev/ttyUSB6')
269                        #if os.path.exists('/dev/ttyUSB7'):
270                                #devices.append('/dev/ttyUSB7')
271                        #if os.path.exists('/dev/ttyUSB8'):
272                                #devices.append('/dev/ttyUSB8')
273                        #if os.path.exists('/dev/ttyUSB9'):
274                                #devices.append('/dev/ttyUSB9')
275                       
276                        #if os.path.exists('/dev/rfcomm0'):
277                                #devices.append('/dev/rfcomm0')
278                        #if os.path.exists('/dev/rfcomm1'):
279                                #devices.append('/dev/rfcomm1')
280                        #if os.path.exists('/dev/rfcomm2'):
281                                #devices.append('/dev/rfcomm2')
282                        #if os.path.exists('/dev/rfcomm3'):
283                                #devices.append('/dev/rfcomm3')
284                        #if os.path.exists('/dev/rfcomm4'):
285                                #devices.append('/dev/rfcomm4')
286                       
287                        #if os.path.exists('/dev/ttyACM0'):
288                                #devices.append('/dev/ttyACM0')
289                        #if os.path.exists('/dev/ttyACM1'):
290                                #devices.append('/dev/ttyACM1')
291                        #if os.path.exists('/dev/ttyACM2'):
292                                #devices.append('/dev/ttyACM2')
293                        #if os.path.exists('/dev/ttyACM3'):
294                                #devices.append('/dev/ttyACM3')
295                        #if os.path.exists('/dev/ttyACM4'):
296                                #devices.append('/dev/ttyACM4')
297               
298               
299                #return(devices)
300       
301       
302        ##################################################################
303       
304        #def hcitoolScanForRemoteDevices(self, devices=[]):
305               
306                #bluetooth_devices = []
307               
308                ##command = '%s scan 2> /dev/null' % PATH_TO_HCITOOL
309                #command = '%s scan' % PATH_TO_HCITOOL
310               
311                #if self.DEBUG > 1:
312                        #print 'INFO: Calling "%s"' % command
313               
314                #output = os.popen(command, 'r')
315               
316                #try:
317                        #result = output.readlines()
318                #except Exception, e:
319                        #if self.DEBUG:
320                                #print "ERROR [Synapse-Interface]: Failed reading result from call to hcitool:",
321                                #print e
322                        #result = ''
323               
324                #if result == '':
325                        #return([]) # Under OS X hcitool doesn't exist so we don't see any devices
326               
327                #for line in result:
328                        #line = line.strip()
329                        #if line == '' or line == 'Scanning ...':
330                                #continue
331                        #elif self.DEBUG > 1:
332                                #print line
333                        #try:
334                                #address = line.split('\t')[0]
335                        #except:
336                                #pass
337                        #else:
338                                #bluetooth_devices.append(address)
339               
340               
341                #for address in bluetooth_devices:
342                       
343                        #command = '%s name %s' % (PATH_TO_HCITOOL, address)
344                       
345                        #if self.DEBUG:
346                                #print 'INFO: Calling "%s"' % command
347                       
348                        #output = os.popen(command, 'r')
349                       
350                        #for line in output.readlines():
351                                #line = line.strip()
352                                #if line == '':
353                                        #continue
354                                #elif self.DEBUG:
355                                        #print '\t',
356                                        #print line
357                               
358                                #device_name = line.strip()
359                       
360                                #if ((device_name == 'MindSet' or device_name == 'MindWave Mobile') and \
361                                        #(address not in devices)):
362                                        #devices.append(address)
363                               
364                                #else:
365                                        #if self.DEBUG:
366                                                #print 'INFO: Found but not recognized: [%s] %s' % \
367                                                        #(address, device_name)
368               
369               
370                #return (devices)
371       
372       
373        ##################################################################
374       
375        #def hcitoolGetActiveConnections(self, devices=[]):
376               
377                #bluetooth_devices = []
378               
379                ##command = '%s con 2> /dev/null' % PATH_TO_HCITOOL
380                #command = '%s con' % PATH_TO_HCITOOL
381               
382                #if self.DEBUG > 1:
383                        #print 'INFO: Calling "%s"' % command
384               
385                #output = os.popen(command, 'r')
386               
387                #try:
388                        #result = output.readlines()
389                #except Exception, e:
390                        #if self.DEBUG:
391                                #print "ERROR [Synapse:Interface]: Failed reading result from call to hcitool:",
392                                #print e
393                        #result = ''
394
395                #if result == '':
396                        #return([]) # Under OS X hcitool doesn't exist so we don't see any devices
397
398                #for line in result:
399                        #line = line.strip()
400                        #if line == '' or line == 'Connections:':
401                                #continue
402                        #elif self.DEBUG > 1:
403                                #print line
404                        #try:
405                                #address = line.split(' ')[2]
406                        #except:
407                                #pass
408                        #else:
409                                #bluetooth_devices.append(address)
410               
411               
412                #for address in bluetooth_devices:
413                       
414                        #command = '%s name %s' % (PATH_TO_HCITOOL, address)
415                       
416                        #if self.DEBUG:
417                                #print 'INFO: Calling "%s":' % command
418                       
419                        #output = os.popen(command, 'r')
420                       
421                        #for line in output.readlines():
422                                #line = line.strip()
423                                #if line == '':
424                                        #continue
425                                #elif self.DEBUG:
426                                        #print '\t',
427                                        #print line
428                               
429                                #device_name = line.strip()
430                       
431                                #if ((device_name == 'MindSet' or device_name == 'MindWave Mobile') and \
432                                        #(address not in devices)):
433                                        #devices.append(address)
434               
435               
436                #return (devices)
437       
438       
439        ##################################################################
440       
441        #def searchForDevices(self):
442               
443                #enable_hcitool = configuration.ENABLE_HCITOOL
444               
445                #devices = []
446               
447                ##self.pushButtonBluetoothSearch.setText('Searching')
448               
449                #if ((sys.platform != 'win32' and sys.platform != 'darwin') and \
450                     #configuration.THINKGEAR_BLUETOOTH_SEARCH):
451                       
452                        ## Bluetooth module doesn't compile properly under Windows
453                        ## and doesn't exist under OS X
454                       
455                        ## PyBluez API Documentation
456                        ## http://pybluez.googlecode.com/svn/www/docs-0.7/index.html
457                       
458                        #bluetooth_devices = []
459                       
460                        #if not enable_hcitool:
461                               
462                                #try:
463                                       
464                                        #if self.DEBUG:
465                                                #print "INFO: Searching for Bluetooth devices using PyBluez module"
466                                       
467                                        #bluetooth_devices = bluetooth.discover_devices( \
468                                              #duration=configuration.THINKGEAR_BLUETOOTH_DISCOVER_DEVICES_TIMEOUT, \
469                                                               #flush_cache=True, \
470                                                               #lookup_names=False)
471                                       
472                                        #for address in bluetooth_devices:
473                                               
474                                                #if self.DEBUG:
475                                                        #print "INFO: Device discovered",
476                                                        #print address
477                                               
478                                                #device_name = bluetooth.lookup_name(address, \
479                                                                 #configuration.THINKGEAR_BLUETOOTH_LOOKUP_NAME_TIMEOUT)
480                                                #if ((device_name == 'MindSet' or device_name == 'MindWave Mobile') and \
481                                                        #(address not in devices)):
482                                                        #devices.append(address)
483                                       
484                                       
485                                        ## There is an issue under recent released of Linux
486                                        ## in which already-connected Bluetooth ThinkGear devices
487                                        ## are not appearing in a bluetooth device scan. However,
488                                        ## using "hcitool" connected devices can be listed correctly.
489                                        ## There does not appear to be an equivalent PyBluez feature.
490                                        ## (http://pybluez.googlecode.com/svn/www/docs-0.7/index.html)
491                                       
492                                        #if devices == []:
493                                                #if self.DEBUG:
494                                                        #print "INFO: No devices found through PyBluez module. Falling back to hcitool."
495                                                #devices = self.hcitoolGetActiveConnections(devices)
496                               
497                               
498                                #except Exception, e:
499                                        #if self.DEBUG:
500                                                #print "ERROR: Exception calling Python Bluetooth module. (Is PyBluez installed?):"
501                                                #print e
502                                       
503                                       
504                                        ##if (sys.platform != 'darwin'):
505                                        #enable_hcitool = True
506                       
507                       
508                        #if enable_hcitool:
509                               
510                                #devices = self.hcitoolScanForRemoteDevices(devices)
511                                #devices = self.hcitoolGetActiveConnections(devices)
512                       
513                       
514                        #if self.DEBUG > 2:
515                                #print "Bluetooth Devices found:",
516                                #print devices
517               
518               
519                #devices = self.searchForSerialDevices(devices)
520               
521               
522                #if self.DEBUG:
523                        #print "Devices found:",
524                        #print devices
525               
526               
527                #return(devices)
528       
529       
530        ##################################################################
531       
532        def collectData(self, source=None, target=None):
533               
534                if source == None:
535                        if self.parent == None:
536                                source = self
537                        else:
538                                source = self.parent
539               
540                if target == None:
541                        if self.parent == None:
542                                target = self
543                        else:
544                                target = self.parent
545               
546                data = {}
547               
548                data['rawEeg'] = source.packets['rawEeg']
549                data['signals'] = source.packets['signals']
550               
551                data['sessionTime'] = self.calculateSessionTime()
552               
553                data['profileName'] = str(target.lineEditSessionProfile.text())
554               
555                return(data)
556       
557       
558        ##################################################################
559       
560        def parseTimeStamp(self, timestamp, local_version=False, truncate_time_zone=False):
561               
562                try:
563                        decimal = '%f' % timestamp
564                        decimal = decimal.split('.')[1]
565                except:
566                        decimal = '0'
567               
568                localtime = time.localtime(timestamp)
569               
570                if local_version:
571                        date = time.strftime('%x', localtime)
572                        localtime = time.strftime('%X', localtime)
573               
574                elif truncate_time_zone:
575                        date = time.strftime('%Y-%m-%d', localtime)
576                        localtime = time.strftime('%H:%M:%S', localtime)
577                        localtime = '%s.%s' % (localtime, decimal[:3])
578               
579                else:
580                        date = time.strftime('%Y-%m-%d', localtime)
581                        localtime = time.strftime('%H:%M:%S', localtime)
582                        localtime = '%s.%s %s' % (localtime, decimal, \
583                                       time.strftime('%Z', time.localtime(timestamp)))
584               
585               
586                return(date, localtime)
587       
588       
589        ##################################################################
590       
591        def saveData(self, source=None, target=None, output_file=None, use_default=False):
592               
593                if source == None:
594                        if self.parent == None:
595                                source = self
596                        else:
597                                source = self.parent
598               
599                if target == None:
600                        if self.parent == None:
601                                target = self
602                        else:
603                                target = self.parent
604               
605                data = self.collectData(source=source, target=target)
606               
607                (date, localtime) = self.parseTimeStamp(time.time())
608               
609                default_filename = '%s %s.synapse' % (date, \
610                                      target.lineEditSessionProfile.text())
611                                     
612                default_filename = os.path.join(self.homepath, default_filename)
613               
614                if output_file == None:
615                       
616                        # use_default controls whether or not a file is automatically saves using the
617                        # default name and path (as opposed to raising a GUI file selection menu)
618                        # whenever an explicit filepath is not defined
619                        if use_default:
620                                       
621                                        output_file = default_filename
622                       
623                        else:
624                       
625                                output_file = QtGui.QFileDialog.getSaveFileName(parent=target, \
626                                                 caption="Save Session Data to File", \
627                                                 dir=default_filename, \
628                                                 filter="Puzzlebox Synapse Data File (*.synapse)")
629                               
630                                try:
631                                        output_file = output_file[0]
632                                except:
633                                        output_file = ''
634               
635               
636                if output_file == '':
637                        return
638               
639                file = open(str(output_file), 'w')
640                pickle.dump(data, file)
641                file.close()
642       
643       
644        ##################################################################
645       
646        def exportData(self, parent=None, source=None, target=None, output_file=None, use_default=False):
647               
648                if parent == None:
649                        if self.parent == None:
650                                parent = self
651                        else:
652                                parent = self.parent
653               
654                if source == None:
655                        if self.parent == None:
656                                source = self
657                        else:
658                                source = self.parent
659               
660                if target == None:
661                        if self.parent == None:
662                                target = self
663                        else:
664                                target = self.parent
665               
666               
667                (date, localtime) = self.parseTimeStamp(time.time())
668               
669                default_filename = '%s %s.csv' % (date, \
670                                      target.lineEditSessionProfile.text())
671               
672                default_filename = os.path.join(target.homepath, default_filename)
673               
674               
675                if output_file == None:
676                       
677                        # use_default controls whether or not a file is automatically saves using the
678                        # default name and path (as opposed to raising a GUI file selection menu)
679                        # whenever an explicit filepath is not defined
680                        if use_default:
681                                       
682                                        output_file = default_filename
683                       
684                        else:
685                                output_file = QtGui.QFileDialog.getSaveFileName(parent=target, \
686                                                 caption="Export Session Data to File", \
687                                                 dir=default_filename, \
688                                                 filter="CSV File (*.csv);;Text File (*.txt)")
689                               
690                                try:
691                                        output_file = output_file[0]
692                                except:
693                                        output_file = ''
694               
695               
696                if output_file == '':
697                        return
698               
699               
700                if str(output_file).endswith('.csv'):
701                       
702                        outputData = self.exportDataToCSV(parent=parent, source=source, target=target)
703               
704               
705                else:
706                       
707                        try:
708                                outputData = self.textEditDebugConsole.toPlainText()
709                        except:
710                                outputData = self.exportDataToCSV()
711               
712               
713                file = open(str(output_file), 'w')
714                file.write(outputData)
715                file.close()
716       
717       
718        ##################################################################
719       
720        def exportDataToCSV(self, parent=None, source=None, target=None):
721               
722                if parent == None:
723                        if self.parent == None:
724                                parent = self
725                        else:
726                                parent = self.parent
727               
728                if source == None:
729                        if self.parent == None:
730                                source = self
731                        else:
732                                source = self.parent
733               
734                if target == None:
735                        if self.parent == None:
736                                target = self
737                        else:
738                                target = self.parent
739               
740                try:
741                        truncate_csv_timezone = target.configuration.EXPORT_CSV_TRUNCATE_TIMEZONE
742                except:
743                        truncate_csv_timezone = False
744               
745                try:
746                        scrub_data = target.configuration.EXPORT_CSV_SCRUB_DATA
747                except:
748                        scrub_data = False
749               
750               
751                headers = 'Date,Time,Attention,Meditation,Signal Level,Delta,Theta,Low Alpha,High Alpha,Low Beta,High Beta,Low Gamma,Mid Gamma'
752               
753                customDataHeaders = []
754                for header in parent.customDataHeaders:
755                        customDataHeaders.append(header)
756                for plugin in parent.activePlugins:
757                        for header in plugin.customDataHeaders:
758                                customDataHeaders.append(header)
759               
760                for each in customDataHeaders:
761                        headers = headers + ',%s' % each
762               
763                headers = headers + '\n'
764               
765                csv = {}
766               
767                for packet in source.packets['signals']:
768                       
769                       
770                        if 'rawEeg' in packet.keys():
771                                continue
772                       
773                        if packet['timestamp'] not in csv.keys():
774                               
775                                if 'blinkStrength' in packet.keys():
776                                        # Skip any blink packets from log
777                                        continue
778                               
779                               
780                                #print packet
781                                timestamp = packet['timestamp']
782                                (date, localtime) = self.parseTimeStamp(timestamp, \
783                                                    truncate_time_zone=truncate_csv_timezone)
784                               
785                                csv[timestamp] = {}
786                                csv[timestamp]['Date'] = date
787                                csv[timestamp]['Time'] = localtime
788                                csv[timestamp]['Attention'] = ''
789                                csv[timestamp]['Meditation'] = ''
790                                csv[timestamp]['Signal Level'] = ''
791                                csv[timestamp]['Delta'] = ''
792                                csv[timestamp]['Theta'] = ''
793                                csv[timestamp]['Low Alpha'] = ''
794                                csv[timestamp]['High Alpha'] = ''
795                                csv[timestamp]['Low Beta'] = ''
796                                csv[timestamp]['High Beta'] = ''
797                                csv[timestamp]['Low Gamma'] = ''
798                                csv[timestamp]['Mid Gamma'] = ''
799                               
800                                for header in customDataHeaders:
801                                        csv[timestamp][header] = ''
802                       
803                       
804                        if 'eSense' in packet.keys():
805                                if 'attention' in packet['eSense'].keys():
806                                        csv[timestamp]['Attention'] = packet['eSense']['attention']
807                                if 'meditation' in packet['eSense'].keys():
808                                        csv[timestamp]['Meditation'] = packet['eSense']['meditation']
809                       
810                        if 'eegPower' in packet.keys():
811                                if 'delta' in packet['eegPower'].keys():
812                                        csv[timestamp]['Delta'] = packet['eegPower']['delta']
813                                if 'theta' in packet['eegPower'].keys():
814                                        csv[timestamp]['Theta'] = packet['eegPower']['theta']
815                                if 'lowAlpha' in packet['eegPower'].keys():
816                                        csv[timestamp]['Low Alpha'] = packet['eegPower']['lowAlpha']
817                                if 'highAlpha' in packet['eegPower'].keys():
818                                        csv[timestamp]['High Alpha'] = packet['eegPower']['highAlpha']
819                                if 'lowBeta' in packet['eegPower'].keys():
820                                        csv[timestamp]['Low Beta'] = packet['eegPower']['lowBeta']
821                                if 'highBeta' in packet['eegPower'].keys():
822                                        csv[timestamp]['High Beta'] = packet['eegPower']['highBeta']
823                                if 'lowGamma' in packet['eegPower'].keys():
824                                        csv[timestamp]['Low Gamma'] = packet['eegPower']['lowGamma']
825                                if 'highGamma' in packet['eegPower'].keys():
826                                        csv[timestamp]['Mid Gamma'] = packet['eegPower']['highGamma']
827                       
828                        if 'poorSignalLevel' in packet.keys():
829                                csv[timestamp]['Signal Level'] = packet['poorSignalLevel']
830                       
831                        for header in customDataHeaders:
832                                if 'custom' in packet.keys() and \
833                                   header in packet['custom'].keys():
834                                        csv[timestamp][header] = packet['custom'][header]
835               
836               
837                if scrub_data:
838                        csv = self.scrubData(csv, truncate_csv_timezone)
839               
840               
841                output = headers
842               
843                csv_keys = csv.keys()
844                csv_keys.sort()
845               
846                for key in csv_keys:
847                       
848                        row = '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s' % \
849                              (csv[key]['Date'], \
850                               csv[key]['Time'], \
851                               csv[key]['Attention'], \
852                               csv[key]['Meditation'], \
853                               csv[key]['Signal Level'], \
854                               csv[key]['Delta'], \
855                               csv[key]['Theta'], \
856                               csv[key]['Low Alpha'], \
857                               csv[key]['High Alpha'], \
858                               csv[key]['Low Beta'], \
859                               csv[key]['High Beta'], \
860                               csv[key]['Low Gamma'], \
861                               csv[key]['Mid Gamma'])
862                       
863                        for header in customDataHeaders:
864                                row = row + ',%s' % csv[key][header]
865                       
866                        row = row + '\n'
867                       
868                        output = output + row
869               
870               
871                return(output)
872       
873       
874        ##################################################################
875       
876        def scrubData(self, csv, truncate_csv_timezone=False):
877               
878                # If there are missing packets, repeat a given packet once per missing
879                # second until there is a gap between 1 and 2 seconds, in which case
880                # produce a final duplicate packet at the mid-point between the packets
881
882                if self.DEBUG:
883                        print "INFO: Scrubbing Data"
884               
885                last_time = None
886                last_recorded_time = None
887               
888                output = {}
889               
890                csv_keys = csv.keys()
891                csv_keys.sort()
892               
893                for key in csv_keys:
894                       
895                        timestamp = key
896
897                        if csv[key]['Attention'] == '':
898                                continue
899                       
900                        if last_time == None:
901                                # First entry in log
902                                last_time = timestamp
903                                last_recorded_time = timestamp
904                                output[key] = csv[key]
905                                continue
906                       
907                        else:
908                               
909                                #time_difference = timestamp - last_time
910                                time_difference = timestamp - last_recorded_time
911                               
912                                if (time_difference <= 1) and \
913                                   (time_difference >= PACKET_MINIMUM_TIME_DIFFERENCE_THRESHOLD):
914                                        # Skip packets within the correct time threshold
915                                        last_time = timestamp
916                                        last_recorded_time = timestamp
917                                        output[key] = csv[key]
918                                        continue
919                               
920                                else:
921                                       
922                                        if self.DEBUG > 1:
923                                                print "time_difference:",
924                                                print time_difference
925                                                print "timestamp:",
926                                                print self.parseTimeStamp(timestamp)[-1].split(' ')[0]
927                                                print "last_time:",
928                                                print self.parseTimeStamp(last_time)[-1].split(' ')[0]
929                                                print "last_recorded_time:",
930                                                print self.parseTimeStamp(last_recorded_time)[-1].split(' ')[0]
931                                       
932                                       
933                                        new_packet = csv[key].copy()
934                                       
935                                        if time_difference >= 2:
936                                               
937                                                ##new_time = last_time + 1
938                                                #new_time = last_recorded_time + 1
939                                               
940                                                count = int(time_difference)
941                                                while count >= 1:
942                                                        new_packet = csv[key].copy()
943                                                        new_time = last_recorded_time + 1
944                                                        (date, formatted_new_time) = self.parseTimeStamp(new_time, \
945                                                         truncate_time_zone=truncate_csv_timezone)
946                                                        new_packet['Time'] = formatted_new_time
947                                                        last_recorded_time = new_time
948                                                        last_time = timestamp
949                                                        output[new_time] = new_packet
950                                                        count = count - 1
951                                                continue
952                                               
953                                        elif time_difference < PACKET_MINIMUM_TIME_DIFFERENCE_THRESHOLD:
954                                                # Spread out "bunched up" packets
955                                                #new_time = last_time + 1
956                                                new_time = last_recorded_time + 1
957                                       
958                                       
959                                        elif (time_difference < 2) and (time_difference > 1):
960                                               
961                                                #new_time = last_time + ((last_time - timestamp) / 2)
962                                                #new_time = last_recorded_time + ((last_recorded_time - timestamp) / 2)
963                                                #new_time = last_time + 1
964                                                new_time = last_recorded_time + 1
965                                       
966                                       
967                                        (date, formatted_new_time) = self.parseTimeStamp(new_time, \
968                                           truncate_time_zone=truncate_csv_timezone)
969                                       
970                                        new_packet['Time'] = formatted_new_time
971                                       
972                                        #last_time = new_time
973                                        last_recorded_time = new_time
974                                        last_time = timestamp
975                                        output[new_time] = new_packet
976                                       
977                                        if self.DEBUG > 1:
978                                                print "WARN: Scrubbing new packet:",
979                                                print new_packet
980                                                print
981               
982               
983                return(output)
984       
985       
986        ##################################################################
987       
988        def resetData(self, source=None):
989               
990                if source == None:
991                        if self.parent == None:
992                                source = self
993                        else:
994                                source = self.parent
995               
996                #if target == None:
997                        #if self.parent == None:
998                                #target = self
999                        #else:
1000                                #target = self.parent
1001               
1002                source.packets['rawEeg'] = []
1003                source.packets['signals'] = []
1004               
1005                source.synapseServer.protocol.session_start_timestamp = \
1006                        time.time()
1007               
1008                source.synapseServer.protocol.packet_count = 0
1009                source.synapseServer.protocol.bad_packets = 0
1010               
1011                self.updateProfileSessionStatus()
1012               
1013                try:
1014                        source.textEditDebugConsole.setText("")
1015                except:
1016                        pass
1017       
1018       
1019        #####################################################################
1020       
1021        def convert_seconds_to_datetime(self, duration):
1022               
1023                duration_hours = duration / (60 * 60)
1024                duration_minutes = (duration - (duration_hours * (60 * 60))) / 60
1025                duration_seconds = (duration - (duration_hours * (60 * 60)) - (duration_minutes * 60))
1026               
1027                duration_hours = '%i' % duration_hours
1028                if (len(duration_hours) == 1):
1029                        duration_hours = "0%s" % duration_hours
1030               
1031                duration_minutes = '%i' % duration_minutes
1032                if (len(duration_minutes) == 1):
1033                        duration_minutes = "0%s" % duration_minutes
1034               
1035                duration_seconds = '%i' % duration_seconds
1036                if (len(duration_seconds) == 1):
1037                        duration_seconds = "0%s" % duration_seconds
1038               
1039                datetime = '%s:%s:%s' % (duration_hours, duration_minutes, duration_seconds)
1040               
1041                return(datetime)
1042
Note: See TracBrowser for help on using the repository browser.