eegdash 0.4.0.dev173498563__py3-none-any.whl → 0.4.1.dev185__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.

Potentially problematic release.


This version of eegdash might be problematic. Click here for more details.

eegdash/hbn/windows.py CHANGED
@@ -21,7 +21,25 @@ from braindecode.datasets.base import BaseConcatDataset
21
21
 
22
22
 
23
23
  def build_trial_table(events_df: pd.DataFrame) -> pd.DataFrame:
24
- """One row per contrast trial with stimulus/response metrics."""
24
+ """Build a table of contrast trials from an events DataFrame.
25
+
26
+ This function processes a DataFrame of events (typically from a BIDS
27
+ `events.tsv` file) to identify contrast trials and extract relevant
28
+ metrics like stimulus onset, response onset, and reaction times.
29
+
30
+ Parameters
31
+ ----------
32
+ events_df : pandas.DataFrame
33
+ A DataFrame containing event information, with at least "onset" and
34
+ "value" columns.
35
+
36
+ Returns
37
+ -------
38
+ pandas.DataFrame
39
+ A DataFrame where each row represents a single contrast trial, with
40
+ columns for onsets, reaction times, and response correctness.
41
+
42
+ """
25
43
  events_df = events_df.copy()
26
44
  events_df["onset"] = pd.to_numeric(events_df["onset"], errors="raise")
27
45
  events_df = events_df.sort_values("onset", kind="mergesort").reset_index(drop=True)
@@ -92,12 +110,13 @@ def build_trial_table(events_df: pd.DataFrame) -> pd.DataFrame:
92
110
  return pd.DataFrame(rows)
93
111
 
94
112
 
95
- # Aux functions to inject the annot
96
113
  def _to_float_or_none(x):
114
+ """Safely convert a value to float or None."""
97
115
  return None if pd.isna(x) else float(x)
98
116
 
99
117
 
100
118
  def _to_int_or_none(x):
119
+ """Safely convert a value to int or None."""
101
120
  if pd.isna(x):
102
121
  return None
103
122
  if isinstance(x, (bool, np.bool_)):
@@ -106,22 +125,55 @@ def _to_int_or_none(x):
106
125
  return int(x)
107
126
  try:
108
127
  return int(x)
109
- except Exception:
128
+ except (ValueError, TypeError):
110
129
  return None
111
130
 
112
131
 
113
132
  def _to_str_or_none(x):
133
+ """Safely convert a value to string or None."""
114
134
  return None if (x is None or (isinstance(x, float) and np.isnan(x))) else str(x)
115
135
 
116
136
 
117
137
  def annotate_trials_with_target(
118
- raw,
119
- target_field="rt_from_stimulus",
120
- epoch_length=2.0,
121
- require_stimulus=True,
122
- require_response=True,
123
- ):
124
- """Create 'contrast_trial_start' annotations with float target in extras."""
138
+ raw: mne.io.Raw,
139
+ target_field: str = "rt_from_stimulus",
140
+ epoch_length: float = 2.0,
141
+ require_stimulus: bool = True,
142
+ require_response: bool = True,
143
+ ) -> mne.io.Raw:
144
+ """Create trial annotations with a specified target value.
145
+
146
+ This function reads the BIDS events file associated with the `raw` object,
147
+ builds a trial table, and creates new MNE annotations for each trial.
148
+ The annotations are labeled "contrast_trial_start" and their `extras`
149
+ dictionary is populated with trial metrics, including a "target" key.
150
+
151
+ Parameters
152
+ ----------
153
+ raw : mne.io.Raw
154
+ The raw data object. Must have a single associated file name from
155
+ which the BIDS path can be derived.
156
+ target_field : str, default "rt_from_stimulus"
157
+ The column from the trial table to use as the "target" value in the
158
+ annotation extras.
159
+ epoch_length : float, default 2.0
160
+ The duration to set for each new annotation.
161
+ require_stimulus : bool, default True
162
+ If True, only include trials that have a recorded stimulus event.
163
+ require_response : bool, default True
164
+ If True, only include trials that have a recorded response event.
165
+
166
+ Returns
167
+ -------
168
+ mne.io.Raw
169
+ The `raw` object with the new annotations set.
170
+
171
+ Raises
172
+ ------
173
+ KeyError
174
+ If `target_field` is not a valid column in the built trial table.
175
+
176
+ """
125
177
  fnames = raw.filenames
126
178
  assert len(fnames) == 1, "Expected a single filename"
127
179
  bids_path = get_bids_path_from_fname(fnames[0])
@@ -152,7 +204,6 @@ def annotate_trials_with_target(
152
204
  extras = []
153
205
  for i, v in enumerate(targets):
154
206
  row = trials.iloc[i]
155
-
156
207
  extras.append(
157
208
  {
158
209
  "target": _to_float_or_none(v),
@@ -169,14 +220,39 @@ def annotate_trials_with_target(
169
220
  onset=onsets,
170
221
  duration=durations,
171
222
  description=descs,
172
- orig_time=raw.info["meas_date"],
223
+ orig_time=raw.info.get("meas_date"),
173
224
  extras=extras,
174
225
  )
175
226
  raw.set_annotations(new_ann, verbose=False)
176
227
  return raw
177
228
 
178
229
 
179
- def add_aux_anchors(raw, stim_desc="stimulus_anchor", resp_desc="response_anchor"):
230
+ def add_aux_anchors(
231
+ raw: mne.io.Raw,
232
+ stim_desc: str = "stimulus_anchor",
233
+ resp_desc: str = "response_anchor",
234
+ ) -> mne.io.Raw:
235
+ """Add auxiliary annotations for stimulus and response onsets.
236
+
237
+ This function inspects existing "contrast_trial_start" annotations and
238
+ adds new, zero-duration "anchor" annotations at the precise onsets of
239
+ stimuli and responses for each trial.
240
+
241
+ Parameters
242
+ ----------
243
+ raw : mne.io.Raw
244
+ The raw data object with "contrast_trial_start" annotations.
245
+ stim_desc : str, default "stimulus_anchor"
246
+ The description for the new stimulus annotations.
247
+ resp_desc : str, default "response_anchor"
248
+ The description for the new response annotations.
249
+
250
+ Returns
251
+ -------
252
+ mne.io.Raw
253
+ The `raw` object with the auxiliary annotations added.
254
+
255
+ """
180
256
  ann = raw.annotations
181
257
  mask = ann.description == "contrast_trial_start"
182
258
  if not np.any(mask):
@@ -189,28 +265,24 @@ def add_aux_anchors(raw, stim_desc="stimulus_anchor", resp_desc="response_anchor
189
265
  ex = ann.extras[idx] if ann.extras is not None else {}
190
266
  t0 = float(ann.onset[idx])
191
267
 
192
- stim_t = ex["stimulus_onset"]
193
- resp_t = ex["response_onset"]
268
+ stim_t = ex.get("stimulus_onset")
269
+ resp_t = ex.get("response_onset")
194
270
 
195
271
  if stim_t is None or (isinstance(stim_t, float) and np.isnan(stim_t)):
196
- rtt = ex["rt_from_trialstart"]
197
- rts = ex["rt_from_stimulus"]
272
+ rtt = ex.get("rt_from_trialstart")
273
+ rts = ex.get("rt_from_stimulus")
198
274
  if rtt is not None and rts is not None:
199
275
  stim_t = t0 + float(rtt) - float(rts)
200
276
 
201
277
  if resp_t is None or (isinstance(resp_t, float) and np.isnan(resp_t)):
202
- rtt = ex["rt_from_trialstart"]
278
+ rtt = ex.get("rt_from_trialstart")
203
279
  if rtt is not None:
204
280
  resp_t = t0 + float(rtt)
205
281
 
206
- if (stim_t is not None) and not (
207
- isinstance(stim_t, float) and np.isnan(stim_t)
208
- ):
282
+ if stim_t is not None and not (isinstance(stim_t, float) and np.isnan(stim_t)):
209
283
  stim_onsets.append(float(stim_t))
210
284
  stim_extras.append(dict(ex, anchor="stimulus"))
211
- if (resp_t is not None) and not (
212
- isinstance(resp_t, float) and np.isnan(resp_t)
213
- ):
285
+ if resp_t is not None and not (isinstance(resp_t, float) and np.isnan(resp_t)):
214
286
  resp_onsets.append(float(resp_t))
215
287
  resp_extras.append(dict(ex, anchor="response"))
216
288
 
@@ -220,7 +292,7 @@ def add_aux_anchors(raw, stim_desc="stimulus_anchor", resp_desc="response_anchor
220
292
  onset=new_onsets,
221
293
  duration=np.zeros_like(new_onsets, dtype=float),
222
294
  description=[stim_desc] * len(stim_onsets) + [resp_desc] * len(resp_onsets),
223
- orig_time=raw.info["meas_date"],
295
+ orig_time=raw.info.get("meas_date"),
224
296
  extras=stim_extras + resp_extras,
225
297
  )
226
298
  raw.set_annotations(ann + aux, verbose=False)
@@ -228,10 +300,10 @@ def add_aux_anchors(raw, stim_desc="stimulus_anchor", resp_desc="response_anchor
228
300
 
229
301
 
230
302
  def add_extras_columns(
231
- windows_concat_ds,
232
- original_concat_ds,
233
- desc="contrast_trial_start",
234
- keys=(
303
+ windows_concat_ds: BaseConcatDataset,
304
+ original_concat_ds: BaseConcatDataset,
305
+ desc: str = "contrast_trial_start",
306
+ keys: tuple = (
235
307
  "target",
236
308
  "rt_from_stimulus",
237
309
  "rt_from_trialstart",
@@ -240,7 +312,31 @@ def add_extras_columns(
240
312
  "correct",
241
313
  "response_type",
242
314
  ),
243
- ):
315
+ ) -> BaseConcatDataset:
316
+ """Add columns from annotation extras to a windowed dataset's metadata.
317
+
318
+ This function propagates trial-level information stored in the `extras`
319
+ of annotations to the `metadata` DataFrame of a `WindowsDataset`.
320
+
321
+ Parameters
322
+ ----------
323
+ windows_concat_ds : BaseConcatDataset
324
+ The windowed dataset whose metadata will be updated.
325
+ original_concat_ds : BaseConcatDataset
326
+ The original (non-windowed) dataset containing the raw data and
327
+ annotations with the `extras` to be added.
328
+ desc : str, default "contrast_trial_start"
329
+ The description of the annotations to source the extras from.
330
+ keys : tuple, default (...)
331
+ The keys to extract from each annotation's `extras` dictionary and
332
+ add as columns to the metadata.
333
+
334
+ Returns
335
+ -------
336
+ BaseConcatDataset
337
+ The `windows_concat_ds` with updated metadata.
338
+
339
+ """
244
340
  float_cols = {
245
341
  "target",
246
342
  "rt_from_stimulus",
@@ -292,7 +388,6 @@ def add_extras_columns(
292
388
  else: # response_type
293
389
  ser = pd.Series(vals, index=md.index, dtype="string")
294
390
 
295
- # Replace the whole column to avoid dtype conflicts
296
391
  md[k] = ser
297
392
 
298
393
  win_ds.metadata = md.reset_index(drop=True)
@@ -303,7 +398,25 @@ def add_extras_columns(
303
398
  return windows_concat_ds
304
399
 
305
400
 
306
- def keep_only_recordings_with(desc, concat_ds):
401
+ def keep_only_recordings_with(
402
+ desc: str, concat_ds: BaseConcatDataset
403
+ ) -> BaseConcatDataset:
404
+ """Filter a concatenated dataset to keep only recordings with a specific annotation.
405
+
406
+ Parameters
407
+ ----------
408
+ desc : str
409
+ The description of the annotation that must be present in a recording
410
+ for it to be kept.
411
+ concat_ds : BaseConcatDataset
412
+ The concatenated dataset to filter.
413
+
414
+ Returns
415
+ -------
416
+ BaseConcatDataset
417
+ A new concatenated dataset containing only the filtered recordings.
418
+
419
+ """
307
420
  kept = []
308
421
  for ds in concat_ds.datasets:
309
422
  if np.any(ds.raw.annotations.description == desc):
eegdash/logging.py CHANGED
@@ -29,6 +29,25 @@ root_logger.setLevel(logging.INFO)
29
29
  # Now, get your package-specific logger. It will inherit the
30
30
  # configuration from the root logger we just set up.
31
31
  logger = logging.getLogger("eegdash")
32
+ """The primary logger for the EEGDash package.
33
+
34
+ This logger is configured to use :class:`rich.logging.RichHandler` for
35
+ formatted, colorful output in the console. It inherits its base configuration
36
+ from the root logger, which is set to the ``INFO`` level.
37
+
38
+ Examples
39
+ --------
40
+ Usage in other modules:
41
+
42
+ .. code-block:: python
43
+
44
+ from .logging import logger
45
+
46
+ logger.info("This is an informational message.")
47
+ logger.warning("This is a warning.")
48
+ logger.error("This is an error.")
49
+ """
50
+
32
51
 
33
52
  logger.setLevel(logging.INFO)
34
53
 
eegdash/mongodb.py CHANGED
@@ -4,50 +4,63 @@
4
4
 
5
5
  """MongoDB connection and operations management.
6
6
 
7
- This module provides thread-safe MongoDB connection management and high-level database
8
- operations for the EEGDash metadata database. It includes methods for finding, adding,
9
- and updating EEG data records with proper connection pooling and error handling.
7
+ This module provides a thread-safe singleton manager for MongoDB connections,
8
+ ensuring that connections to the database are handled efficiently and consistently
9
+ across the application.
10
10
  """
11
11
 
12
12
  import threading
13
13
 
14
14
  from pymongo import MongoClient
15
-
16
- # MongoDB Operations
17
- # These methods provide a high-level interface to interact with the MongoDB
18
- # collection, allowing users to find, add, and update EEG data records.
19
- # - find:
20
- # - exist:
21
- # - add_request:
22
- # - add:
23
- # - update_request:
24
- # - remove_field:
25
- # - remove_field_from_db:
26
- # - close: Close the MongoDB connection.
27
- # - __del__: Destructor to close the MongoDB connection.
15
+ from pymongo.collection import Collection
16
+ from pymongo.database import Database
28
17
 
29
18
 
30
19
  class MongoConnectionManager:
31
- """Singleton class to manage MongoDB client connections."""
20
+ """A thread-safe singleton to manage MongoDB client connections.
21
+
22
+ This class ensures that only one connection instance is created for each
23
+ unique combination of a connection string and staging flag. It provides
24
+ class methods to get a client and to close all active connections.
25
+
26
+ Attributes
27
+ ----------
28
+ _instances : dict
29
+ A dictionary to store singleton instances, mapping a
30
+ (connection_string, is_staging) tuple to a (client, db, collection)
31
+ tuple.
32
+ _lock : threading.Lock
33
+ A lock to ensure thread-safe instantiation of clients.
34
+
35
+ """
32
36
 
33
- _instances = {}
37
+ _instances: dict[tuple[str, bool], tuple[MongoClient, Database, Collection]] = {}
34
38
  _lock = threading.Lock()
35
39
 
36
40
  @classmethod
37
- def get_client(cls, connection_string: str, is_staging: bool = False):
38
- """Get or create a MongoDB client for the given connection string and staging flag.
41
+ def get_client(
42
+ cls, connection_string: str, is_staging: bool = False
43
+ ) -> tuple[MongoClient, Database, Collection]:
44
+ """Get or create a MongoDB client for the given connection parameters.
45
+
46
+ This method returns a cached client if one already exists for the given
47
+ connection string and staging flag. Otherwise, it creates a new client,
48
+ connects to the appropriate database ("eegdash" or "eegdashstaging"),
49
+ and returns the client, database, and "records" collection.
39
50
 
40
51
  Parameters
41
52
  ----------
42
53
  connection_string : str
43
- The MongoDB connection string
44
- is_staging : bool
45
- Whether to use staging database
54
+ The MongoDB connection string.
55
+ is_staging : bool, default False
56
+ If True, connect to the staging database ("eegdashstaging").
57
+ Otherwise, connect to the production database ("eegdash").
46
58
 
47
59
  Returns
48
60
  -------
49
- tuple
50
- A tuple of (client, database, collection)
61
+ tuple[MongoClient, Database, Collection]
62
+ A tuple containing the connected MongoClient instance, the Database
63
+ object, and the Collection object for the "records" collection.
51
64
 
52
65
  """
53
66
  # Create a unique key based on connection string and staging flag
@@ -66,8 +79,12 @@ class MongoConnectionManager:
66
79
  return cls._instances[key]
67
80
 
68
81
  @classmethod
69
- def close_all(cls):
70
- """Close all MongoDB client connections."""
82
+ def close_all(cls) -> None:
83
+ """Close all managed MongoDB client connections.
84
+
85
+ This method iterates through all cached client instances and closes
86
+ their connections. It also clears the instance cache.
87
+ """
71
88
  with cls._lock:
72
89
  for client, _, _ in cls._instances.values():
73
90
  try:
eegdash/paths.py CHANGED
@@ -18,12 +18,22 @@ from mne.utils import get_config as mne_get_config
18
18
 
19
19
 
20
20
  def get_default_cache_dir() -> Path:
21
- """Resolve a consistent default cache directory for EEGDash.
21
+ """Resolve the default cache directory for EEGDash data.
22
+
23
+ The function determines the cache directory based on the following
24
+ priority order:
25
+
26
+ 1. The path specified by the ``EEGDASH_CACHE_DIR`` environment variable.
27
+ 2. The path specified by the ``MNE_DATA`` configuration in the MNE-Python
28
+ config file.
29
+ 3. A hidden directory named ``.eegdash_cache`` in the current working
30
+ directory.
31
+
32
+ Returns
33
+ -------
34
+ pathlib.Path
35
+ The resolved, absolute path to the default cache directory.
22
36
 
23
- Priority order:
24
- 1) Environment variable ``EEGDASH_CACHE_DIR`` if set.
25
- 2) MNE config ``MNE_DATA`` if set (aligns with tests and ecosystem caches).
26
- 3) ``.eegdash_cache`` under the current working directory.
27
37
  """
28
38
  # 1) Explicit env var wins
29
39
  env_dir = os.environ.get("EEGDASH_CACHE_DIR")
eegdash/utils.py CHANGED
@@ -11,7 +11,22 @@ including MongoDB client initialization and configuration helpers.
11
11
  from mne.utils import get_config, set_config, use_log_level
12
12
 
13
13
 
14
- def _init_mongo_client():
14
+ def _init_mongo_client() -> None:
15
+ """Initialize the default MongoDB connection URI in the MNE config.
16
+
17
+ This function checks if the ``EEGDASH_DB_URI`` is already set in the
18
+ MNE-Python configuration. If it is not set, this function sets it to the
19
+ default public EEGDash MongoDB Atlas cluster URI.
20
+
21
+ The operation is performed with MNE's logging level temporarily set to
22
+ "ERROR" to suppress verbose output.
23
+
24
+ Notes
25
+ -----
26
+ This is an internal helper function and is not intended for direct use
27
+ by end-users.
28
+
29
+ """
15
30
  with use_log_level("ERROR"):
16
31
  if get_config("EEGDASH_DB_URI") is None:
17
32
  set_config(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eegdash
3
- Version: 0.4.0.dev173498563
3
+ Version: 0.4.1.dev185
4
4
  Summary: EEG data for machine learning
5
5
  Author-email: Young Truong <dt.young112@gmail.com>, Arnaud Delorme <adelorme@gmail.com>, Aviv Dotan <avivd220@gmail.com>, Oren Shriki <oren70@gmail.com>, Bruno Aristimunha <b.aristimunha@gmail.com>
6
6
  License-Expression: GPL-3.0-only
@@ -27,23 +27,17 @@ License-File: LICENSE
27
27
  Requires-Dist: braindecode>=1.0
28
28
  Requires-Dist: mne_bids>=0.17.0
29
29
  Requires-Dist: numba
30
- Requires-Dist: numpy
31
- Requires-Dist: pandas
32
- Requires-Dist: pybids
33
30
  Requires-Dist: pymongo
34
- Requires-Dist: python-dotenv
35
31
  Requires-Dist: s3fs
36
- Requires-Dist: scipy
37
32
  Requires-Dist: tqdm
38
- Requires-Dist: h5io>=0.2.4
39
33
  Requires-Dist: pymatreader
40
34
  Requires-Dist: eeglabio
41
35
  Requires-Dist: tabulate
42
- Requires-Dist: docstring_inheritance
43
36
  Requires-Dist: rich
44
37
  Provides-Extra: tests
45
38
  Requires-Dist: pytest; extra == "tests"
46
39
  Requires-Dist: pytest-cov; extra == "tests"
40
+ Requires-Dist: pytest-sugar; extra == "tests"
47
41
  Requires-Dist: codecov; extra == "tests"
48
42
  Requires-Dist: pytest_cases; extra == "tests"
49
43
  Requires-Dist: pytest-benchmark; extra == "tests"
@@ -66,10 +60,15 @@ Requires-Dist: lightgbm; extra == "docs"
66
60
  Requires-Dist: plotly; extra == "docs"
67
61
  Requires-Dist: nbformat; extra == "docs"
68
62
  Requires-Dist: graphviz; extra == "docs"
63
+ Requires-Dist: neato; extra == "docs"
64
+ Provides-Extra: digestion
65
+ Requires-Dist: pybids; extra == "digestion"
66
+ Requires-Dist: python-dotenv; extra == "digestion"
69
67
  Provides-Extra: all
70
68
  Requires-Dist: eegdash[docs]; extra == "all"
71
69
  Requires-Dist: eegdash[dev]; extra == "all"
72
70
  Requires-Dist: eegdash[tests]; extra == "all"
71
+ Requires-Dist: eegdash[digestion]; extra == "all"
73
72
  Dynamic: license-file
74
73
 
75
74
  # EEG-Dash
@@ -0,0 +1,38 @@
1
+ eegdash/__init__.py,sha256=GEDA8-xE1JPDzIRGN6fmVpGsBOFd2_uNrnAxp-UuN6w,704
2
+ eegdash/api.py,sha256=saCl7_9tvblPVeTWZphw8fRXW4A2t1t2JBBp-RDvq1M,19632
3
+ eegdash/bids_eeg_metadata.py,sha256=kEmFUe07tivkuIoC5T-YwfO4QQYJBxuc769ZBV1UCKo,16682
4
+ eegdash/const.py,sha256=9WMetN7YMQJbkN2PhzItxtVRZ4VBXLP82vFu9pY6xok,9066
5
+ eegdash/downloader.py,sha256=Z-9EEJildqJxIihwdtXc_h9kzCkuF9LWIwQEfyG9Huw,6030
6
+ eegdash/logging.py,sha256=OQ4jMtwv1h-gzjxmr3PCpcsKi5-3Nhd3r9PJ4UN7oQI,1467
7
+ eegdash/mongodb.py,sha256=9FJDeEebOD5RzNYfAf1lhr0R-pECAlnug6Sjhd9_oUw,3469
8
+ eegdash/paths.py,sha256=iXzBUindjIwgkf2k0Phm2InChOfPZNGilQmGwJ8zNO0,1507
9
+ eegdash/utils.py,sha256=u_fQ8DiA1b7dVLzwzZBhm8H-LUk6dga54WyqbbqYEJ4,1282
10
+ eegdash/dataset/__init__.py,sha256=EXmCtcIWz2_iq7-04AzOPmOxfv1hvUGnrSRgu_Je800,975
11
+ eegdash/dataset/base.py,sha256=dHCiUtoZddflLpUD-q2yIDImMfcIVZmTuvRRJflVS8s,11718
12
+ eegdash/dataset/bids_dataset.py,sha256=577D_kqig4xmW_fYz1VbaUbGWPquL33eT97ge_CbXpQ,14919
13
+ eegdash/dataset/dataset.py,sha256=IDAGg5qDeh1R48nFMiyG6_9CxenS2KK56VeuvM_w5tM,27593
14
+ eegdash/dataset/dataset_summary.csv,sha256=YJX-BitOyo-5nsHBd3ECIY1u7lFBjMQAFfCUPLYEgpo,25289
15
+ eegdash/dataset/registry.py,sha256=5TOCWalA0RV7omRoYS0OzdcSaOTvXvqos74_Vj2jv0M,9127
16
+ eegdash/features/__init__.py,sha256=BXNhjvL4_SSFAY1lcP9nyGpkbJNtoOMH4AHlF6OyABo,4078
17
+ eegdash/features/datasets.py,sha256=79Xey6SouPHMKybF78madVl5i7P0f03jnostBV6Dr7M,24880
18
+ eegdash/features/decorators.py,sha256=Gvk-5VtqatpH7BBVVV3pcz1KJKygd-ZU8mniR_Tpvlw,4052
19
+ eegdash/features/extractors.py,sha256=R4csU3jj95xndtWI1VuMKoKi26xprzmuOp9wcy9iVzI,11937
20
+ eegdash/features/inspect.py,sha256=GpNV4708XPn4LXl5BXy8e0GNr_DSrojxjAT9c7POxqk,4373
21
+ eegdash/features/serialization.py,sha256=f981K8DcfaLZ0q98IBrXeAbMHnPmKBbp7cFiXZnjezw,4194
22
+ eegdash/features/utils.py,sha256=SuvPE6N_ccm-Ar4g-1dgVj1qaW2bV9hNQivtz946hlY,6487
23
+ eegdash/features/feature_bank/__init__.py,sha256=YsMXLC1FEtHL3IEw9pYw1fc5IY0x_hr2qWQowI5gZj8,2991
24
+ eegdash/features/feature_bank/complexity.py,sha256=eOLN0X_xaS15ZpLPDQcychuwjL459-FqZKYfOG51z-g,3366
25
+ eegdash/features/feature_bank/connectivity.py,sha256=bQ6KlxWm5GNpCS9ypLqBUr2L171Yq7wpBQT2tRQKTZ4,2159
26
+ eegdash/features/feature_bank/csp.py,sha256=jKPrmqBj7FliybNbg035cVZddvVSkhk9OazcscDpipU,3303
27
+ eegdash/features/feature_bank/dimensionality.py,sha256=Pit3YNxv64-qHUyz_5c3nBo4sFD5AnCE5mTwgnzSndc,3980
28
+ eegdash/features/feature_bank/signal.py,sha256=iSMrgnZLKNn1qNdBPheEoE_UcJPPLAOv3qDTaRI1BcE,3431
29
+ eegdash/features/feature_bank/spectral.py,sha256=bNB7skusePs1gX7NOU6yRlw_Gr4UOCkO_ylkCgybzug,3319
30
+ eegdash/features/feature_bank/utils.py,sha256=zCdkfDMLWJhPjBqb5Xz0jLKg8gm3qQDY1G1rZTLuCaM,1354
31
+ eegdash/hbn/__init__.py,sha256=hsI5pmIuYDzr--aE5UiToO-P9XL5fVRKahZzdsAodro,794
32
+ eegdash/hbn/preprocessing.py,sha256=xp0HBz8WGhLI5c2Zkk4QiVUzGoIZep8YypnHNZsUJ4o,3800
33
+ eegdash/hbn/windows.py,sha256=Z_fhG3kaHd5MAPg60FwFnxMJay8EzacXytUaCsOENGc,14408
34
+ eegdash-0.4.1.dev185.dist-info/licenses/LICENSE,sha256=asisR-xupy_NrQBFXnx6yqXeZcYWLvbAaiETl25iXT0,931
35
+ eegdash-0.4.1.dev185.dist-info/METADATA,sha256=kprps0odUjO5HR9uFhU6L1GCUFf69AqfX91lSh5ojkM,6880
36
+ eegdash-0.4.1.dev185.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ eegdash-0.4.1.dev185.dist-info/top_level.txt,sha256=zavO69HQ6MyZM0aQMR2zUS6TAFc7bnN5GEpDpOpFZzU,8
38
+ eegdash-0.4.1.dev185.dist-info/RECORD,,