BCI2000Tools 1.0.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- BCI2000Tools/AllTools.py +48 -0
- BCI2000Tools/Bootstrapping.py +145 -0
- BCI2000Tools/Chain.py +775 -0
- BCI2000Tools/Container.py +440 -0
- BCI2000Tools/ElectrodeGrids.py +590 -0
- BCI2000Tools/ElectrodePositions.py +601 -0
- BCI2000Tools/Electrodes.py +1657 -0
- BCI2000Tools/EventRelated.py +906 -0
- BCI2000Tools/Expressions.py +117 -0
- BCI2000Tools/FileReader.py +676 -0
- BCI2000Tools/LoadStream2Mat.py +154 -0
- BCI2000Tools/Numerics.py +359 -0
- BCI2000Tools/Parameters.py +950 -0
- BCI2000Tools/Plotting.py +1049 -0
- BCI2000Tools/Remote.py +249 -0
- BCI2000Tools/TimingAnalysis.py +332 -0
- BCI2000Tools/__init__.py +40 -0
- bci2000tools-1.0.0.dist-info/METADATA +50 -0
- bci2000tools-1.0.0.dist-info/RECORD +21 -0
- bci2000tools-1.0.0.dist-info/WHEEL +6 -0
- bci2000tools-1.0.0.dist-info/top_level.txt +1 -0
BCI2000Tools/AllTools.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
__all__ = [
|
|
2
|
+
'ForgetBCI2000Tools',
|
|
3
|
+
]
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
import glob
|
|
7
|
+
|
|
8
|
+
thisSubmoduleName = os.path.splitext( os.path.basename( __file__ ) )[ 0 ]
|
|
9
|
+
parentDir = os.path.realpath( os.path.dirname( __file__ ) )
|
|
10
|
+
parentModuleName = os.path.basename( parentDir )
|
|
11
|
+
submodulePaths = sorted( glob.glob( os.path.join( parentDir, '*.py' ) ) )
|
|
12
|
+
iskosher = lambda x: x.replace( '/', '' ).replace( '\\', '' ).replace( '_', '' ).replace( '.', '' ).isalnum()
|
|
13
|
+
submodulePaths = [ submodulePath for submodulePath in submodulePaths if iskosher( submodulePath[ len( parentDir ): ] ) ]
|
|
14
|
+
sub = None
|
|
15
|
+
allItems = {}
|
|
16
|
+
provenance = {}
|
|
17
|
+
print( '# The path to %s is %s' % ( parentModuleName, parentDir.replace( '\\', '/' ) ) )
|
|
18
|
+
from . import Bootstrapping; from .Bootstrapping import bci2000path, bci2000_exe_extension
|
|
19
|
+
for submodulePath in submodulePaths:
|
|
20
|
+
submoduleName = os.path.splitext( os.path.basename( submodulePath ) )[ 0 ] # NB: this assumes no sub-sub-modules (flat structure inside BCI2000Tools directory)
|
|
21
|
+
if submoduleName in ( '__init__', '__main__', thisSubmoduleName ): continue
|
|
22
|
+
msg = 'from %s.%s import *' % ( parentModuleName, submoduleName )
|
|
23
|
+
canaries = []
|
|
24
|
+
if submoduleName in [ 'Remote' ]:
|
|
25
|
+
canaries.append( 'prog/BCI2000Remote.py' )
|
|
26
|
+
if submoduleName in [ 'Chain' ]:
|
|
27
|
+
exeExtension = bci2000_exe_extension('tools/cmdline')
|
|
28
|
+
canaries.append( 'tools/cmdline/bci_dat2stream' + exeExtension )
|
|
29
|
+
canaries.append( 'tools/cmdline/bci_stream2hybrid' + exeExtension )
|
|
30
|
+
deadCanaries = [ canary for canary in canaries if not os.path.exists( bci2000path( canary ) ) ]
|
|
31
|
+
if deadCanaries:
|
|
32
|
+
print( '#%s # skipped (no %s)' % ( msg, deadCanaries[ 0 ] ) )
|
|
33
|
+
continue
|
|
34
|
+
print( msg )
|
|
35
|
+
exec( 'import %s.%s as sub' % ( parentModuleName, submoduleName ) )
|
|
36
|
+
for name in sub.__all__:
|
|
37
|
+
item = getattr( sub, name )
|
|
38
|
+
if item is not allItems.get( name, item ): print( '# WARNING: %s from %s.%s overwrites %s from %s.%s' % ( name, parentModuleName, submoduleName, name, parentModuleName, provenance[ name ] ) )
|
|
39
|
+
allItems[ name ] = item
|
|
40
|
+
provenance[ name ] = submoduleName
|
|
41
|
+
|
|
42
|
+
__all__ += allItems.keys()
|
|
43
|
+
locals().update( allItems )
|
|
44
|
+
|
|
45
|
+
def ForgetBCI2000Tools():
|
|
46
|
+
for k in list( sys.modules ):
|
|
47
|
+
if k.startswith( parentModuleName + '.' ): del sys.modules[ k ]
|
|
48
|
+
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# ///////////////////////////////////////////////////////////////////////////
|
|
4
|
+
# $Id: Bootstrapping.py 9000 2025-08-05 18:07:32Z jhill $
|
|
5
|
+
# Author: jeremy.hill@neurotechcenter.org
|
|
6
|
+
# Description: infer/specify/use the location of the BCI2000 distribution
|
|
7
|
+
#
|
|
8
|
+
# $BEGIN_BCI2000_LICENSE$
|
|
9
|
+
#
|
|
10
|
+
# This file is part of BCI2000, a platform for real-time bio-signal research.
|
|
11
|
+
# [ Copyright (C) 2000-2022: BCI2000 team and many external contributors ]
|
|
12
|
+
#
|
|
13
|
+
# BCI2000 is free software: you can redistribute it and/or modify it under the
|
|
14
|
+
# terms of the GNU General Public License as published by the Free Software
|
|
15
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
|
16
|
+
# version.
|
|
17
|
+
#
|
|
18
|
+
# BCI2000 is distributed in the hope that it will be useful, but
|
|
19
|
+
# WITHOUT ANY WARRANTY
|
|
20
|
+
# - without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
21
|
+
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
22
|
+
#
|
|
23
|
+
# You should have received a copy of the GNU General Public License along with
|
|
24
|
+
# this program. If not, see <http://www.gnu.org/licenses/>.
|
|
25
|
+
#
|
|
26
|
+
# $END_BCI2000_LICENSE$
|
|
27
|
+
# ///////////////////////////////////////////////////////////////////////////
|
|
28
|
+
"""
|
|
29
|
+
Use `bci2000root()` to set the path to the root directory of the BCI2000
|
|
30
|
+
distribution you want to use. It will be stored as a global variable in the
|
|
31
|
+
module and remembered for the rest of the session.
|
|
32
|
+
|
|
33
|
+
Use `bci2000path()` to resolve partial paths relative to the currently
|
|
34
|
+
configured `bci2000root()` setting.
|
|
35
|
+
|
|
36
|
+
By default, when you first import this submodule, it attempts to set
|
|
37
|
+
`bci2000root()` based on the assumption that the module itself is installed
|
|
38
|
+
within the `tools/python` subtree of the relevant BCI2000 distribution
|
|
39
|
+
(perhaps using `pip install -e`, as recommended in our `setup.py` file). If
|
|
40
|
+
this fails, `bci2000root()` will be left as `None`.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
'bci2000root', 'bci2000path',
|
|
45
|
+
'bci2000_exe_extension',
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
import os
|
|
49
|
+
import sys
|
|
50
|
+
import inspect
|
|
51
|
+
|
|
52
|
+
if sys.version < '3': bytes = str
|
|
53
|
+
else: unicode = str; basestring = ( unicode, bytes )
|
|
54
|
+
|
|
55
|
+
BCI2000_ROOT_DIR = None
|
|
56
|
+
|
|
57
|
+
def bci2000root( set=None ):
|
|
58
|
+
"""
|
|
59
|
+
Specify, or query, the absolute path to the root directory of the BCI2000
|
|
60
|
+
distribution (the parent directory of `batch`, `parms`, `prog` and `tools`).
|
|
61
|
+
|
|
62
|
+
If this has been set, `bci2000chain()` will look for command-line binaries
|
|
63
|
+
in the `tools/cmdline` subdirectory of the root, by default.
|
|
64
|
+
"""
|
|
65
|
+
global BCI2000_ROOT_DIR
|
|
66
|
+
if set is not None: BCI2000_ROOT_DIR = os.path.realpath( os.path.expanduser( set ) )
|
|
67
|
+
return BCI2000_ROOT_DIR
|
|
68
|
+
|
|
69
|
+
def bci2000path( partial_path ):
|
|
70
|
+
"""
|
|
71
|
+
If `bci2000root()` has been set, and the specified `partial_path` exists
|
|
72
|
+
relative to it, join them together and return the resulting absolute path.
|
|
73
|
+
|
|
74
|
+
If not, just return the result of `os.path.realpath(partial_path)`.
|
|
75
|
+
"""
|
|
76
|
+
if isinstance( partial_path, basestring ) and isinstance( BCI2000_ROOT_DIR, basestring ) and not os.path.exists( partial_path ) and os.path.exists( os.path.join( BCI2000_ROOT_DIR, partial_path ) ):
|
|
77
|
+
return os.path.realpath( os.path.join( BCI2000_ROOT_DIR, partial_path ) )
|
|
78
|
+
return os.path.realpath( partial_path )
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# Now let's automatically try to fill in a default for BCI2000_ROOT_DIR based
|
|
82
|
+
# on the location of this Python module itself.
|
|
83
|
+
|
|
84
|
+
class NoParentDirectory( ValueError ): pass
|
|
85
|
+
|
|
86
|
+
def WhereAmI( nFileSystemLevelsUp=1, nStackLevelsBack=0 ):
|
|
87
|
+
"""
|
|
88
|
+
`WhereAmI( 0 )` is equivalent to `__file__`
|
|
89
|
+
|
|
90
|
+
`WhereAmI()` or `WhereAmI(1)` gives you the current source file's
|
|
91
|
+
parent directory.
|
|
92
|
+
"""
|
|
93
|
+
my_getfile = inspect.getfile
|
|
94
|
+
if getattr( sys, 'frozen', False ) and hasattr( sys, '_MEIPASS' ):
|
|
95
|
+
# sys._MEIPASS indicates that we're in PyInstaller which, in a surprise reversal
|
|
96
|
+
# of the old py2exe situation, supports `__file__` but NOT `inspect.getfile()`.
|
|
97
|
+
# The following workaround is adapted from
|
|
98
|
+
# http://lists.swapbytes.de/archives/obspy-users/2017-April/002395.html
|
|
99
|
+
def my_getfile( object ):
|
|
100
|
+
if inspect.isframe( object ):
|
|
101
|
+
try: return object.f_globals[ '__file__' ]
|
|
102
|
+
except: pass
|
|
103
|
+
return inspect.getfile( object )
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
frame = inspect.currentframe()
|
|
107
|
+
for i in range( abs( nStackLevelsBack ) + 1 ):
|
|
108
|
+
frame = frame.f_back
|
|
109
|
+
file = my_getfile( frame )
|
|
110
|
+
finally:
|
|
111
|
+
del frame # https://docs.python.org/3/library/inspect.html#the-interpreter-stack
|
|
112
|
+
result = file = os.path.realpath( file )
|
|
113
|
+
nFileSystemLevelsUp = abs( nFileSystemLevelsUp )
|
|
114
|
+
for i in range( nFileSystemLevelsUp ):
|
|
115
|
+
pardir = os.path.dirname( result )
|
|
116
|
+
if pardir == result: raise NoParentDirectory( 'cannot go %d file-system levels up from %s (maximum is %d)' % ( nFileSystemLevelsUp, file, i ) )
|
|
117
|
+
result = pardir
|
|
118
|
+
return result
|
|
119
|
+
|
|
120
|
+
try: candidate = WhereAmI( 4 ) # assume we are in $BCI2000_ROOT_DIR/tools/python/BCI2000Tools/Bootstrapping.py ...
|
|
121
|
+
except NoParentDirectory: pass
|
|
122
|
+
else:
|
|
123
|
+
for partial in [ 'tools/python' ]: # but if we go up 4 levels and don't find all the partial paths in this list beneath us, cancel that assumption
|
|
124
|
+
if not os.path.isdir( os.path.join( candidate, *partial.split( '/' ) ) ): break
|
|
125
|
+
else: # if no break has occurred
|
|
126
|
+
BCI2000_ROOT_DIR = candidate
|
|
127
|
+
|
|
128
|
+
def bci2000_exe_extension(where=None):
|
|
129
|
+
if where is None:
|
|
130
|
+
where = 'tools/cmdline' if os.path.isdir( bci2000path( 'tools/cmdline' ) ) else 'prog'
|
|
131
|
+
if sys.platform.lower().startswith( 'win' ):
|
|
132
|
+
return '.exe'
|
|
133
|
+
elif sys.platform.lower().startswith( 'darwin' ):
|
|
134
|
+
if where == 'tools/cmdline':
|
|
135
|
+
what = os.path.join( bci2000path( where ), 'bci_dat2stream' )
|
|
136
|
+
if os.path.exists( what + '.app' ) and not os.path.isfile( what ): return '.app'
|
|
137
|
+
else: return ''
|
|
138
|
+
elif where == 'prog':
|
|
139
|
+
what = os.path.join( bci2000path( where ), 'Operator' )
|
|
140
|
+
if os.path.isfile( what ) and not os.path.exists( what + '.app' ): return ''
|
|
141
|
+
else: return '.app'
|
|
142
|
+
else:
|
|
143
|
+
raise ValueError( 'unsupported test location %r' % where )
|
|
144
|
+
else:
|
|
145
|
+
return ''
|