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

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