lunapi 0.1.1__cp312-cp312-macosx_10_9_x86_64.whl → 0.1.2__cp312-cp312-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-312-darwin.so +0 -0
- lunapi/lunapi1.py +70 -25
- {lunapi-0.1.1.dist-info → lunapi-0.1.2.dist-info}/METADATA +9 -8
- lunapi-0.1.2.dist-info/RECORD +8 -0
- {lunapi-0.1.1.dist-info → lunapi-0.1.2.dist-info}/WHEEL +1 -1
- lunapi-0.1.1.dist-info/RECORD +0 -8
- {lunapi-0.1.1.dist-info → lunapi-0.1.2.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, 14-Nov-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"""
|
@@ -799,16 +843,16 @@ class inst:
|
|
799
843
|
return df
|
800
844
|
|
801
845
|
# --------------------------------------------------------------------------------
|
802
|
-
def psd( self, ch, var = 'PSD' , minf = None, maxf =
|
846
|
+
def psd( self, ch, var = 'PSD' , minf = None, maxf = 25, minp = None, maxp = None , xlines = None , ylines = None ):
|
803
847
|
"""Generates a PSD plot (from PSD or MTM)"""
|
804
848
|
if ch is None: return
|
805
849
|
if type(ch) is not list: ch = [ ch ]
|
806
850
|
|
807
851
|
if var == 'PSD':
|
808
|
-
self.eval( 'PSD spectrum dB sig=' + ','.join(ch) )
|
852
|
+
self.eval( 'PSD spectrum dB max=' + str(maxf) + ' sig=' + ','.join(ch) )
|
809
853
|
df = self.table( 'PSD' , 'CH_F' )
|
810
854
|
else:
|
811
|
-
self.eval( 'MTM tw=15 dB sig=' + ','.join(ch) )
|
855
|
+
self.eval( 'MTM tw=15 dB max=' + str(maxf) + ' sig=' + ','.join(ch) )
|
812
856
|
df = self.table( 'MTM' , 'CH_F' )
|
813
857
|
|
814
858
|
psd( df = df , ch = ch , var = var ,
|
@@ -817,16 +861,16 @@ class inst:
|
|
817
861
|
|
818
862
|
|
819
863
|
# --------------------------------------------------------------------------------
|
820
|
-
def spec( self, ch, var = 'PSD' , mine = None, maxe = None, minf = None, maxf =
|
864
|
+
def spec( self, ch, var = 'PSD' , mine = None, maxe = None, minf = None, maxf = 25 , w = 0.025 ):
|
821
865
|
"""Generates an epoch-level PSD spectrogram (from PSD or MTM)"""
|
822
866
|
if ch is None: return
|
823
867
|
if type(ch) is not list: ch = [ ch ]
|
824
868
|
|
825
869
|
if var == 'PSD':
|
826
|
-
self.eval( 'PSD epoch-spectrum dB sig=' + ','.join(ch) )
|
870
|
+
self.eval( 'PSD epoch-spectrum dB max=' + str(maxf) + ' sig=' + ','.join(ch) )
|
827
871
|
df = self.table( 'PSD' , 'CH_E_F' )
|
828
872
|
else:
|
829
|
-
self.eval( 'MTM epoch-spectra epoch epoch-output dB tw=15 sig=' + ','.join(ch) )
|
873
|
+
self.eval( 'MTM epoch-spectra epoch epoch-output dB tw=15 max=' + str(maxf) + ' sig=' + ','.join(ch) )
|
830
874
|
df = self.table( 'MTM' , 'CH_E_F' )
|
831
875
|
|
832
876
|
spec( df = df , ch = None , var = var ,
|
@@ -1130,13 +1174,13 @@ class inst:
|
|
1130
1174
|
return spec( res , ch=ch, var='PSD', mine=mine,maxe=maxe,minf=minf,maxf=maxf,w=w)
|
1131
1175
|
|
1132
1176
|
# --------------------------------------------------------------------------------
|
1133
|
-
def psd(self, ch, minf = None, maxf =
|
1177
|
+
def psd(self, ch, minf = None, maxf = 25, minp = None, maxp = None , xlines = None , ylines = None ):
|
1134
1178
|
"""Spectrogram plot for a given channel 'ch'"""
|
1135
1179
|
if type( ch ) is not str:
|
1136
1180
|
return
|
1137
1181
|
if all( self.has( ch ) ) is not True:
|
1138
1182
|
return
|
1139
|
-
res = self.silent_proc(
|
1183
|
+
res = self.silent_proc( 'PSD spectrum dB max=' + str(maxf) + ' sig=' + ','.join(ch) )[ 'PSD: CH_F' ]
|
1140
1184
|
return psd( res , ch, minf = minf, maxf = maxf, minp = minp, maxp = maxp , xlines = xlines , ylines = ylines )
|
1141
1185
|
|
1142
1186
|
|
@@ -2140,12 +2184,12 @@ def scope( p,
|
|
2140
2184
|
if band_hjorth_sel.value is True:
|
2141
2185
|
S = np.transpose( ss.get_hjorths( pow_sel.value ) )
|
2142
2186
|
S = np.asarray(S,dtype=object)
|
2143
|
-
S[np.isnan(S.astype(np.
|
2187
|
+
S[np.isnan(S.astype(np.float64))] = None
|
2144
2188
|
bg.update_traces({'z': S } , selector = {'type':'heatmap'} )
|
2145
2189
|
else:
|
2146
2190
|
S = np.transpose( ss.get_bands( pow_sel.value ) )
|
2147
2191
|
S = np.asarray(S,dtype=object)
|
2148
|
-
S[np.isnan(S.astype(np.
|
2192
|
+
S[np.isnan(S.astype(np.float64))] = None
|
2149
2193
|
bg.update_traces({'z': S } , selector = {'type':'heatmap'} )
|
2150
2194
|
|
2151
2195
|
def pop_a1(change):
|
@@ -2276,6 +2320,10 @@ def scope( p,
|
|
2276
2320
|
update_bandpower(None)
|
2277
2321
|
ss.set_scaling( len(chbox.value) , len( anbox.value) , 2**float(yscale.value) , float(yspace.value) , header_height, footer_height , annot_height )
|
2278
2322
|
|
2323
|
+
ss.window( 0 , 30 )
|
2324
|
+
epoch.value = str(1);
|
2325
|
+
|
2326
|
+
redraw()
|
2279
2327
|
return container_app
|
2280
2328
|
|
2281
2329
|
|
@@ -2293,7 +2341,7 @@ class moonbeam:
|
|
2293
2341
|
""" Initiate Moonbeam with an NSRR token """
|
2294
2342
|
self.nsrr_tok = nsrr_tok
|
2295
2343
|
self.df1 = self.cohorts()
|
2296
|
-
if cdir is None: cdir = os.path.join( tempfile.gettempdir() , 'luna-
|
2344
|
+
if cdir is None: cdir = os.path.join( tempfile.gettempdir() , 'luna-moonbeam' )
|
2297
2345
|
self.set_cache(cdir)
|
2298
2346
|
|
2299
2347
|
def set_cache(self,cdir):
|
@@ -2330,21 +2378,20 @@ class moonbeam:
|
|
2330
2378
|
return self.df2
|
2331
2379
|
|
2332
2380
|
|
2333
|
-
def inst(self, iid
|
2334
|
-
""" Create an instance of a record, either downloaded or cached """
|
2381
|
+
def inst(self, iid ):
|
2382
|
+
""" Create an instance of a record, either downloaded or cached """
|
2335
2383
|
if self.df2 is None: return
|
2336
2384
|
if self.curr_cohort is None: return
|
2337
2385
|
|
2338
2386
|
# ensure we have this file
|
2339
|
-
self.pull( iid ,
|
2387
|
+
self.pull( iid , self.curr_cohort )
|
2340
2388
|
|
2341
|
-
#
|
2342
|
-
proj1 = proj()
|
2389
|
+
# ensure we have a proj (from proj singleton)
|
2390
|
+
proj1 = proj(False)
|
2343
2391
|
p = proj1.inst( self.curr_id )
|
2344
|
-
|
2345
2392
|
edf1 = str( pathlib.Path( self.cdir ).joinpath( self.curr_edf ).expanduser().resolve() )
|
2346
2393
|
p.attach_edf( edf1 )
|
2347
|
-
|
2394
|
+
|
2348
2395
|
if self.curr_annot is not None:
|
2349
2396
|
annot1 = str( pathlib.Path( self.cdir ).joinpath( self.curr_annot ).expanduser().resolve() )
|
2350
2397
|
p.attach_annot( annot1 )
|
@@ -2353,10 +2400,8 @@ class moonbeam:
|
|
2353
2400
|
return p
|
2354
2401
|
|
2355
2402
|
|
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 )
|
2403
|
+
def pull(self, iid , cohort ):
|
2404
|
+
""" Download an individual record (if not already cached) """
|
2360
2405
|
if self.df2.empty: return False
|
2361
2406
|
|
2362
2407
|
# iid
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lunapi
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.2
|
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,14 @@ 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
|
30
31
|
Requires-Dist: IPython
|
31
32
|
Description-Content-Type: text/markdown
|
32
33
|
|
@@ -0,0 +1,8 @@
|
|
1
|
+
lunapi-0.1.2.dist-info/RECORD,,
|
2
|
+
lunapi-0.1.2.dist-info/WHEEL,sha256=1ev3JdwAIPi5J-6GtgubjU6JTZhBWShbCqvblqPTDlE,115
|
3
|
+
lunapi-0.1.2.dist-info/METADATA,sha256=4UDU9iWO816l1GO-_UmLTWQt3x-bbaEN9Lttdkls9Ic,1489
|
4
|
+
lunapi-0.1.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
5
|
+
lunapi/__init__.py,sha256=cDep9d2N4KKUt81AzHUyFsuRdGwxCD1rqqFmptsAqsk,352
|
6
|
+
lunapi/lunapi1.py,sha256=J1Bzz8Hz_6ybgfBcbhtQMAWSuJrYZ7aI4lGEPyP1zao,92373
|
7
|
+
lunapi/lunapi0.cpython-312-darwin.so,sha256=7yYQywS_xoTA61WAkWj4k6iBq61MlAEgGBbWgnPQxyQ,19104512
|
8
|
+
lunapi/lunapi0.cpp,sha256=nQ5cwNdm4fvZ5TSDSxrgWu8Luw1r6NyDsvDWu9sLv7I,13053
|
lunapi-0.1.1.dist-info/RECORD
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
lunapi/__init__.py,sha256=cDep9d2N4KKUt81AzHUyFsuRdGwxCD1rqqFmptsAqsk,352
|
2
|
-
lunapi/lunapi1.py,sha256=hzz8h9G2SEg2WIW-eN1oF6JKPZGZcGP4nSWvtf9iToM,90993
|
3
|
-
lunapi/lunapi0.cpython-312-darwin.so,sha256=EDOYiH-tN2IBuWE2L_yuSFW90U-UYJHTFYHcd9bP_sE,18480336
|
4
|
-
lunapi/lunapi0.cpp,sha256=BCVMWAyJNKM8mnUFU7yRioH2TGyph5iIt85wxBE8kKo,12728
|
5
|
-
lunapi-0.1.1.dist-info/RECORD,,
|
6
|
-
lunapi-0.1.1.dist-info/WHEEL,sha256=XQpPvMhBuuI7CO5YhweQijP5VYf7nMik1q6oVfoESKw,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
|