lunapi 0.1.1__cp312-cp312-macosx_11_0_arm64.whl → 1.2.0__cp312-cp312-macosx_11_0_arm64.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 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 empty lunapi-instance" )
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.1, 30-May-2024
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.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.float_))] = None
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.float_))] = None
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-mmonbeam' )
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, cohort = None ):
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 , cohort )
2386
+ self.pull( iid , self.curr_cohort )
2340
2387
 
2341
- # initiate an instance (from singleton proj)
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 = None ):
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: 0.1.1
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: matplotlib
24
- Requires-Dist: pandas
25
- Requires-Dist: numpy
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=bS2kxwU1pioFffhNQmlfvjD0H1flBf5ZtxV4jDj8Nvc,114
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/__init__.py,sha256=cDep9d2N4KKUt81AzHUyFsuRdGwxCD1rqqFmptsAqsk,352
6
+ lunapi/lunapi1.py,sha256=oSN4_0zEW5tKzTEfvp5Fc6qdsJPu0_qZdaG-d5hhZu8,92343
7
+ lunapi/lunapi0.cpython-312-darwin.so,sha256=zZiXkWoNPqrI3Gf1d0xsKV8yrI14NHZ9dpVCJY3JJ7w,15867680
8
+ lunapi/lunapi0.cpp,sha256=nQ5cwNdm4fvZ5TSDSxrgWu8Luw1r6NyDsvDWu9sLv7I,13053
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: scikit-build-core 0.9.4
2
+ Generator: scikit-build-core 0.10.7
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp312-cp312-macosx_11_0_arm64
5
5
 
@@ -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=bSG8YlPFdaLVVvK1vGIydRPX9WY1wptxFa6c6SNVzHc,15173184
4
- lunapi/lunapi0.cpp,sha256=BCVMWAyJNKM8mnUFU7yRioH2TGyph5iIt85wxBE8kKo,12728
5
- lunapi-0.1.1.dist-info/RECORD,,
6
- lunapi-0.1.1.dist-info/WHEEL,sha256=V_AcIM3vgYk_Ca9jzxyPzvxd48JurhIwqptcCCWNybw,113
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