lunapi 0.1.1__cp310-cp310-macosx_10_9_x86_64.whl → 1.2.0__cp310-cp310-macosx_10_9_x86_64.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.
- lunapi/lunapi0.cpp +9 -2
- lunapi/lunapi0.cpython-310-darwin.so +0 -0
- lunapi/lunapi1.py +105 -61
- {lunapi-0.1.1.dist-info → lunapi-1.2.0.dist-info}/METADATA +10 -8
- lunapi-1.2.0.dist-info/RECORD +8 -0
- {lunapi-0.1.1.dist-info → lunapi-1.2.0.dist-info}/WHEEL +1 -1
- lunapi-0.1.1.dist-info/RECORD +0 -8
- {lunapi-0.1.1.dist-info → lunapi-1.2.0.dist-info}/licenses/LICENSE +0 -0
lunapi/lunapi0.cpp
CHANGED
@@ -66,7 +66,9 @@ PYBIND11_MODULE(lunapi0, m) {
|
|
66
66
|
.def( "get_sample_list" ,
|
67
67
|
&lunapi_t::sample_list,
|
68
68
|
"Return the loaded sample list" )
|
69
|
-
|
69
|
+
.def( "validate_sample_list" ,
|
70
|
+
&lunapi_t::validate_sample_list ,
|
71
|
+
"Validate an attached sample list" )
|
70
72
|
.def( "insert_inst" , &lunapi_t::insert_inst )
|
71
73
|
.def( "nobs" , &lunapi_t::nobs )
|
72
74
|
.def( "clear" , &lunapi_t::clear )
|
@@ -112,8 +114,13 @@ PYBIND11_MODULE(lunapi0, m) {
|
|
112
114
|
.def( "inst" ,
|
113
115
|
py::overload_cast<const std::string&>
|
114
116
|
(&lunapi_t::inst,py::const_),
|
115
|
-
"Generate an
|
117
|
+
"Generate an lunapi-instance" )
|
116
118
|
|
119
|
+
.def( "empty_inst" ,
|
120
|
+
py::overload_cast<const std::string&,const int, const int, const std::string&, const std::string&>
|
121
|
+
(&lunapi_t::inst,py::const_),
|
122
|
+
"Generate an empty lunapi-instance of fixed record size" )
|
123
|
+
|
117
124
|
.def( "inst" ,
|
118
125
|
py::overload_cast<const std::string&,const std::string &>
|
119
126
|
(&lunapi_t::inst,py::const_),
|
Binary file
|
lunapi/lunapi1.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
"""lunapi1 module: a high-level wrapper around lunapi0 module functions"""
|
2
2
|
|
3
3
|
# Luna Python interface (lunapi)
|
4
|
-
# v0.1.
|
4
|
+
# v0.1.2, 17-Dec-2024
|
5
5
|
|
6
6
|
import lunapi.lunapi0 as _luna
|
7
7
|
|
@@ -33,7 +33,7 @@ class resources:
|
|
33
33
|
POPS_LIB = 's2'
|
34
34
|
MODEL_PATH = '/build/luna-models/'
|
35
35
|
|
36
|
-
lp_version = "v0.1.
|
36
|
+
lp_version = "v0.1.2"
|
37
37
|
|
38
38
|
# C++ singleton class (engine & sample list)
|
39
39
|
# lunapi_t --> luna
|
@@ -83,7 +83,11 @@ class proj:
|
|
83
83
|
a list of folder names and optional arguments to be passed to build
|
84
84
|
|
85
85
|
"""
|
86
|
-
|
86
|
+
|
87
|
+
# first clear any existing sample list
|
88
|
+
proj.eng.clear()
|
89
|
+
|
90
|
+
# then try to build a new one
|
87
91
|
if type( args ) is not list: args = [ args ]
|
88
92
|
return proj.eng.build_sample_list( args )
|
89
93
|
|
@@ -144,6 +148,28 @@ class proj:
|
|
144
148
|
|
145
149
|
return proj.eng.nobs()
|
146
150
|
|
151
|
+
#------------------------------------------------------------------------
|
152
|
+
|
153
|
+
def validate( self ):
|
154
|
+
"""Validates an internal sample-list
|
155
|
+
|
156
|
+
This provides the same functionality
|
157
|
+
as the `--validate` option of Luna, which is described here:
|
158
|
+
|
159
|
+
https://zzz.bwh.harvard.edu/luna/ref/helpers/#-validate
|
160
|
+
|
161
|
+
Parameters
|
162
|
+
----------
|
163
|
+
none
|
164
|
+
|
165
|
+
"""
|
166
|
+
|
167
|
+
tbl = proj.eng.validate_sample_list()
|
168
|
+
tbl = pd.DataFrame( tbl )
|
169
|
+
tbl.columns = [ 'ID' , 'Filename', 'Valid' ]
|
170
|
+
tbl.index += 1
|
171
|
+
return tbl
|
172
|
+
|
147
173
|
|
148
174
|
#------------------------------------------------------------------------
|
149
175
|
|
@@ -173,6 +199,24 @@ class proj:
|
|
173
199
|
return inst(proj.eng.inst( n ))
|
174
200
|
|
175
201
|
|
202
|
+
#------------------------------------------------------------------------
|
203
|
+
|
204
|
+
def empty_inst( self, id, nr, rs, startdate = '01.01.00', starttime = '00.00.00' ):
|
205
|
+
"""Generates a new instance with empty fixed-size EDF"""
|
206
|
+
|
207
|
+
# check inputs
|
208
|
+
nr = int( nr )
|
209
|
+
rs = int( rs )
|
210
|
+
if nr < 0:
|
211
|
+
print( "expecting nr (number of records) to be a positive integer" )
|
212
|
+
return
|
213
|
+
if rs < 0:
|
214
|
+
print( "expecting rs (record duration, secs) to be a positive integer" )
|
215
|
+
return
|
216
|
+
|
217
|
+
# return instance of fixed size
|
218
|
+
return inst(proj.eng.empty_inst(id, nr, rs, startdate, starttime ))
|
219
|
+
|
176
220
|
#------------------------------------------------------------------------
|
177
221
|
def clear(self):
|
178
222
|
"""Clears any existing project sample-list"""
|
@@ -798,40 +842,6 @@ class inst:
|
|
798
842
|
#df = df.drop(columns = ['ID','TP','MID','INTERVAL'] )
|
799
843
|
return df
|
800
844
|
|
801
|
-
# --------------------------------------------------------------------------------
|
802
|
-
def psd( self, ch, var = 'PSD' , minf = None, maxf = None, minp = None, maxp = None , xlines = None , ylines = None ):
|
803
|
-
"""Generates a PSD plot (from PSD or MTM)"""
|
804
|
-
if ch is None: return
|
805
|
-
if type(ch) is not list: ch = [ ch ]
|
806
|
-
|
807
|
-
if var == 'PSD':
|
808
|
-
self.eval( 'PSD spectrum dB sig=' + ','.join(ch) )
|
809
|
-
df = self.table( 'PSD' , 'CH_F' )
|
810
|
-
else:
|
811
|
-
self.eval( 'MTM tw=15 dB sig=' + ','.join(ch) )
|
812
|
-
df = self.table( 'MTM' , 'CH_F' )
|
813
|
-
|
814
|
-
psd( df = df , ch = ch , var = var ,
|
815
|
-
minf = minf , maxf = maxf , minp = minp , maxp = maxp ,
|
816
|
-
xlines = xlines , ylines = ylines )
|
817
|
-
|
818
|
-
|
819
|
-
# --------------------------------------------------------------------------------
|
820
|
-
def spec( self, ch, var = 'PSD' , mine = None, maxe = None, minf = None, maxf = None , w = 0.025 ):
|
821
|
-
"""Generates an epoch-level PSD spectrogram (from PSD or MTM)"""
|
822
|
-
if ch is None: return
|
823
|
-
if type(ch) is not list: ch = [ ch ]
|
824
|
-
|
825
|
-
if var == 'PSD':
|
826
|
-
self.eval( 'PSD epoch-spectrum dB sig=' + ','.join(ch) )
|
827
|
-
df = self.table( 'PSD' , 'CH_E_F' )
|
828
|
-
else:
|
829
|
-
self.eval( 'MTM epoch-spectra epoch epoch-output dB tw=15 sig=' + ','.join(ch) )
|
830
|
-
df = self.table( 'MTM' , 'CH_E_F' )
|
831
|
-
|
832
|
-
spec( df = df , ch = None , var = var ,
|
833
|
-
mine = mine , maxe = maxe , minf = minf , maxf = maxf , w = w )
|
834
|
-
|
835
845
|
|
836
846
|
# --------------------------------------------------------------------------------
|
837
847
|
# tfview : spectral regional viewer
|
@@ -1119,7 +1129,49 @@ class inst:
|
|
1119
1129
|
if type(ch) is not list: ch = [ ch ]
|
1120
1130
|
return self.edf.has_channels( ch )
|
1121
1131
|
|
1122
|
-
# --------------------------------------------------------------------------------
|
1132
|
+
# --------------------------------------------------------------------------------
|
1133
|
+
# def psd(self, ch, minf = None, maxf = 25, minp = None, maxp = None , xlines = None , ylines = None ):
|
1134
|
+
# """Spectrogram plot for a given channel 'ch'"""
|
1135
|
+
# if type( ch ) is not str: return
|
1136
|
+
# if all( self.has( ch ) ) is not True: return
|
1137
|
+
# res = self.silent_proc( 'PSD spectrum dB max=' + str(maxf) + ' sig=' + ','.join(ch) )[ 'PSD: CH_F' ]
|
1138
|
+
# return psd( res , ch, minf = minf, maxf = maxf, minp = minp, maxp = maxp , xlines = xlines , ylines = ylines )
|
1139
|
+
|
1140
|
+
# --------------------------------------------------------------------------------
|
1141
|
+
def psd( self, ch, var = 'PSD' , minf = None, maxf = 25, minp = None, maxp = None , xlines = None , ylines = None ):
|
1142
|
+
"""Generates a PSD plot (from PSD or MTM) for one or more channel(s)"""
|
1143
|
+
if ch is None: return
|
1144
|
+
if type(ch) is not list: ch = [ ch ]
|
1145
|
+
|
1146
|
+
if var == 'PSD':
|
1147
|
+
res = self.silent_proc( 'PSD spectrum dB max=' + str(maxf) + ' sig=' + ','.join(ch) )
|
1148
|
+
df = res[ 'PSD: CH_F' ]
|
1149
|
+
else:
|
1150
|
+
res = self.silent_proc( 'MTM tw=15 dB max=' + str(maxf) + ' sig=' + ','.join(ch) )
|
1151
|
+
df = res[ 'MTM: CH_F' ]
|
1152
|
+
|
1153
|
+
psd( df = df , ch = ch , var = var ,
|
1154
|
+
minf = minf , maxf = maxf , minp = minp , maxp = maxp ,
|
1155
|
+
xlines = xlines , ylines = ylines )
|
1156
|
+
|
1157
|
+
|
1158
|
+
# --------------------------------------------------------------------------------
|
1159
|
+
# def spec( self, ch, var = 'PSD' , mine = None, maxe = None, minf = None, maxf = 25 , w = 0.025 ):
|
1160
|
+
# """Generates an epoch-level PSD spectrogram (from PSD or MTM)"""
|
1161
|
+
# if ch is None: return
|
1162
|
+
# if type(ch) is not list: ch = [ ch ]
|
1163
|
+
#
|
1164
|
+
# if var == 'PSD':
|
1165
|
+
# self.eval( 'PSD epoch-spectrum dB max=' + str(maxf) + ' sig=' + ','.join(ch) )
|
1166
|
+
# df = self.table( 'PSD' , 'CH_E_F' )
|
1167
|
+
# else:
|
1168
|
+
# self.eval( 'MTM epoch-spectra epoch epoch-output dB tw=15 max=' + str(maxf) + ' sig=' + ','.join(ch) )
|
1169
|
+
# df = self.table( 'MTM' , 'CH_E_F' )
|
1170
|
+
#
|
1171
|
+
# spec( df = df , ch = None , var = var ,
|
1172
|
+
# mine = mine , maxe = maxe , minf = minf , maxf = maxf , w = w )
|
1173
|
+
|
1174
|
+
# --------------------------------------------------------------------------------
|
1123
1175
|
def spec(self,ch,mine = None , maxe = None , minf = None, maxf = None, w = 0.025 ):
|
1124
1176
|
"""PSD given channel 'ch'"""
|
1125
1177
|
if type( ch ) is not str:
|
@@ -1129,15 +1181,6 @@ class inst:
|
|
1129
1181
|
res = self.silent_proc( "PSD epoch-spectrum dB sig="+ch )[ 'PSD: CH_E_F' ]
|
1130
1182
|
return spec( res , ch=ch, var='PSD', mine=mine,maxe=maxe,minf=minf,maxf=maxf,w=w)
|
1131
1183
|
|
1132
|
-
# --------------------------------------------------------------------------------
|
1133
|
-
def psd(self, ch, minf = None, maxf = None, minp = None, maxp = None , xlines = None , ylines = None ):
|
1134
|
-
"""Spectrogram plot for a given channel 'ch'"""
|
1135
|
-
if type( ch ) is not str:
|
1136
|
-
return
|
1137
|
-
if all( self.has( ch ) ) is not True:
|
1138
|
-
return
|
1139
|
-
res = self.silent_proc( "PSD spectrum dB sig="+ch )[ 'PSD: CH_F' ]
|
1140
|
-
return psd( res , ch, minf = minf, maxf = maxf, minp = minp, maxp = maxp , xlines = xlines , ylines = ylines )
|
1141
1184
|
|
1142
1185
|
|
1143
1186
|
# --------------------------------------------------------------------------------
|
@@ -2140,12 +2183,12 @@ def scope( p,
|
|
2140
2183
|
if band_hjorth_sel.value is True:
|
2141
2184
|
S = np.transpose( ss.get_hjorths( pow_sel.value ) )
|
2142
2185
|
S = np.asarray(S,dtype=object)
|
2143
|
-
S[np.isnan(S.astype(np.
|
2186
|
+
S[np.isnan(S.astype(np.float64))] = None
|
2144
2187
|
bg.update_traces({'z': S } , selector = {'type':'heatmap'} )
|
2145
2188
|
else:
|
2146
2189
|
S = np.transpose( ss.get_bands( pow_sel.value ) )
|
2147
2190
|
S = np.asarray(S,dtype=object)
|
2148
|
-
S[np.isnan(S.astype(np.
|
2191
|
+
S[np.isnan(S.astype(np.float64))] = None
|
2149
2192
|
bg.update_traces({'z': S } , selector = {'type':'heatmap'} )
|
2150
2193
|
|
2151
2194
|
def pop_a1(change):
|
@@ -2276,6 +2319,10 @@ def scope( p,
|
|
2276
2319
|
update_bandpower(None)
|
2277
2320
|
ss.set_scaling( len(chbox.value) , len( anbox.value) , 2**float(yscale.value) , float(yspace.value) , header_height, footer_height , annot_height )
|
2278
2321
|
|
2322
|
+
ss.window( 0 , 30 )
|
2323
|
+
epoch.value = str(1);
|
2324
|
+
|
2325
|
+
redraw()
|
2279
2326
|
return container_app
|
2280
2327
|
|
2281
2328
|
|
@@ -2293,7 +2340,7 @@ class moonbeam:
|
|
2293
2340
|
""" Initiate Moonbeam with an NSRR token """
|
2294
2341
|
self.nsrr_tok = nsrr_tok
|
2295
2342
|
self.df1 = self.cohorts()
|
2296
|
-
if cdir is None: cdir = os.path.join( tempfile.gettempdir() , 'luna-
|
2343
|
+
if cdir is None: cdir = os.path.join( tempfile.gettempdir() , 'luna-moonbeam' )
|
2297
2344
|
self.set_cache(cdir)
|
2298
2345
|
|
2299
2346
|
def set_cache(self,cdir):
|
@@ -2330,21 +2377,20 @@ class moonbeam:
|
|
2330
2377
|
return self.df2
|
2331
2378
|
|
2332
2379
|
|
2333
|
-
def inst(self, iid
|
2334
|
-
""" Create an instance of a record, either downloaded or cached """
|
2380
|
+
def inst(self, iid ):
|
2381
|
+
""" Create an instance of a record, either downloaded or cached """
|
2335
2382
|
if self.df2 is None: return
|
2336
2383
|
if self.curr_cohort is None: return
|
2337
2384
|
|
2338
2385
|
# ensure we have this file
|
2339
|
-
self.pull( iid ,
|
2386
|
+
self.pull( iid , self.curr_cohort )
|
2340
2387
|
|
2341
|
-
#
|
2342
|
-
proj1 = proj()
|
2388
|
+
# ensure we have a proj (from proj singleton)
|
2389
|
+
proj1 = proj(False)
|
2343
2390
|
p = proj1.inst( self.curr_id )
|
2344
|
-
|
2345
2391
|
edf1 = str( pathlib.Path( self.cdir ).joinpath( self.curr_edf ).expanduser().resolve() )
|
2346
2392
|
p.attach_edf( edf1 )
|
2347
|
-
|
2393
|
+
|
2348
2394
|
if self.curr_annot is not None:
|
2349
2395
|
annot1 = str( pathlib.Path( self.cdir ).joinpath( self.curr_annot ).expanduser().resolve() )
|
2350
2396
|
p.attach_annot( annot1 )
|
@@ -2353,10 +2399,8 @@ class moonbeam:
|
|
2353
2399
|
return p
|
2354
2400
|
|
2355
2401
|
|
2356
|
-
def pull(self, iid , cohort
|
2357
|
-
""" Download an individual record (if not already cached) """
|
2358
|
-
if cohort is None and self.df2.empty: return False
|
2359
|
-
if self.df2.empty: files( cohort )
|
2402
|
+
def pull(self, iid , cohort ):
|
2403
|
+
""" Download an individual record (if not already cached) """
|
2360
2404
|
if self.df2.empty: return False
|
2361
2405
|
|
2362
2406
|
# iid
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lunapi
|
3
|
-
Version:
|
3
|
+
Version: 1.2.0
|
4
4
|
Summary: Python interface to the Luna toolset for sleep signal analysis
|
5
5
|
Keywords: Sleep,EEG,PSG,Luna,Signal processing
|
6
6
|
Author-Email: Shaun Purcell <smpurcell@bwh.harvard.edu>, Senthil Palanivelu <spalanivelu@mgh.harvard.edu>, Nataliia Kozhemiako <nkozhemiako@bwh.harvard.edu>
|
@@ -20,13 +20,15 @@ Classifier: Programming Language :: Python :: 3.13
|
|
20
20
|
Project-URL: Www, https://zzz.bwh.harvard.edu/luna
|
21
21
|
Project-URL: Github, http://github.com/remnrem/luna-api
|
22
22
|
Requires-Python: >=3.9
|
23
|
-
Requires-Dist:
|
24
|
-
Requires-Dist:
|
25
|
-
Requires-Dist:
|
26
|
-
Requires-Dist: scipy
|
27
|
-
Requires-Dist: plotly
|
28
|
-
Requires-Dist: nbformat
|
29
|
-
Requires-Dist: ipywidgets
|
23
|
+
Requires-Dist: pandas<3,>=2
|
24
|
+
Requires-Dist: numpy>=2
|
25
|
+
Requires-Dist: matplotlib<4.0,>=3
|
26
|
+
Requires-Dist: scipy<2,>=1
|
27
|
+
Requires-Dist: plotly<6,>=5
|
28
|
+
Requires-Dist: nbformat<6,>=5
|
29
|
+
Requires-Dist: ipywidgets<9,>=8
|
30
|
+
Requires-Dist: tqdm<5,>=4
|
31
|
+
Requires-Dist: requests<3,>=2
|
30
32
|
Requires-Dist: IPython
|
31
33
|
Description-Content-Type: text/markdown
|
32
34
|
|
@@ -0,0 +1,8 @@
|
|
1
|
+
lunapi-1.2.0.dist-info/RECORD,,
|
2
|
+
lunapi-1.2.0.dist-info/WHEEL,sha256=CQCn-Gg7FyA1vyNSzvE34YdeHxf8WzJQKMn4oS65uIg,115
|
3
|
+
lunapi-1.2.0.dist-info/METADATA,sha256=1-TAzaUSJf5OCha4HlTOS8dNcBMH5QAC9dmm3rxLyB0,1519
|
4
|
+
lunapi-1.2.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
5
|
+
lunapi/lunapi0.cpython-310-darwin.so,sha256=hEG3vwwnr0X3rE2yhuedfm7IM0wDSuq4vOja8qIA9jc,19155712
|
6
|
+
lunapi/__init__.py,sha256=cDep9d2N4KKUt81AzHUyFsuRdGwxCD1rqqFmptsAqsk,352
|
7
|
+
lunapi/lunapi1.py,sha256=oSN4_0zEW5tKzTEfvp5Fc6qdsJPu0_qZdaG-d5hhZu8,92343
|
8
|
+
lunapi/lunapi0.cpp,sha256=nQ5cwNdm4fvZ5TSDSxrgWu8Luw1r6NyDsvDWu9sLv7I,13053
|
lunapi-0.1.1.dist-info/RECORD
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
lunapi/lunapi0.cpython-310-darwin.so,sha256=1CbbnMT5fkk7UrU7vQ0ENzW6ZzF74IF85YwjyfT8lCo,18463864
|
2
|
-
lunapi/__init__.py,sha256=cDep9d2N4KKUt81AzHUyFsuRdGwxCD1rqqFmptsAqsk,352
|
3
|
-
lunapi/lunapi1.py,sha256=hzz8h9G2SEg2WIW-eN1oF6JKPZGZcGP4nSWvtf9iToM,90993
|
4
|
-
lunapi/lunapi0.cpp,sha256=BCVMWAyJNKM8mnUFU7yRioH2TGyph5iIt85wxBE8kKo,12728
|
5
|
-
lunapi-0.1.1.dist-info/RECORD,,
|
6
|
-
lunapi-0.1.1.dist-info/WHEEL,sha256=krbo6XhnUQXR8ZQGAdjyrn-0wATirW0sbgQtk6A0vDg,114
|
7
|
-
lunapi-0.1.1.dist-info/METADATA,sha256=qlb2AHZBxKUVFvm_ePq5TWBd_YRqZWmlTcAtl8V4zZE,1422
|
8
|
-
lunapi-0.1.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
File without changes
|