lunapi.edf_utils

EDF manipulation and annotation analysis utilities.

Wraps luna command-line tools for operations not directly exposed through the Python bindings: EDF merging/binding and multi-sample annotation overlap analysis.

Functions

merge_edfs(files[, edf, id, slist, fixed, luna_bin])

Concatenate EDFs in time (row-bind).

bind_edfs(files[, edf, id, slist, luna_bin])

Bind EDFs by adding channels (column-bind).

overlap(files, seed[, other, bg, nreps, event_perm, ...])

Multi-sample annotation overlap / enrichment analysis.

Module Contents

lunapi.edf_utils.merge_edfs(files, edf='merged.edf', id='merged', slist=None, fixed=False, luna_bin=None)[source]

Concatenate EDFs in time (row-bind).

Mirrors luna --merge. EDFs are ordered by their embedded start timestamps unless fixed=True, in which case they are concatenated in the order supplied. If there are gaps between recordings the output is written as EDF+D (discontinuous).

Parameters:
  • files (list of str) – EDF file paths to merge.

  • edf (str) – Output EDF filename (default 'merged.edf').

  • id (str) – EDF record ID for the merged file (default 'merged').

  • slist (str, optional) – If given, write a one-row Luna sample-list to this path.

  • fixed (bool) – If True, ignore file timestamps and concatenate in list order.

  • luna_bin (str, optional) – Path to the luna binary. Defaults to searching PATH.

Returns:

Path to the written output EDF.

Return type:

pathlib.Path

Examples

>>> lp.merge_edfs(['night1.edf', 'night2.edf'], edf='both_nights.edf', id='subj1')
PosixPath('both_nights.edf')
lunapi.edf_utils.bind_edfs(files, edf='merged.edf', id='merged', slist=None, luna_bin=None)[source]

Bind EDFs by adding channels (column-bind).

Mirrors luna --bind. All EDFs must share the same start time and number of records. Channels may have different sample rates.

Parameters:
  • files (list of str) – EDF file paths to bind.

  • edf (str) – Output EDF filename (default 'merged.edf').

  • id (str) – EDF record ID for the bound file (default 'merged').

  • slist (str, optional) – If given, write a one-row Luna sample-list to this path.

  • luna_bin (str, optional) – Path to the luna binary. Defaults to searching PATH.

Returns:

Path to the written output EDF.

Return type:

pathlib.Path

Examples

>>> lp.bind_edfs(['eeg.edf', 'eog.edf', 'emg.edf'], edf='psg.edf', id='subj1')
PosixPath('psg.edf')
lunapi.edf_utils.overlap(files, seed, other=None, bg=None, nreps=1000, event_perm=False, event_perm_w=None, w=None, out=None, luna_bin=None, **kwargs)[source]

Multi-sample annotation overlap / enrichment analysis.

Mirrors luna --overlap. Pools annotation events across individuals into a single virtual timeline, then tests whether seed annotations overlap with other annotations (or themselves) more than expected by chance, assessed by permutation.

Parameters:
  • files (dict, list, DataFrame, or str) –

    Per-individual annotation files. Accepted forms:

    dict

    {'id1': 'id1.annot', 'id2': 'id2.annot', ...}

    list

    [('id1', 'path'), ('id2', 'path'), ...] or a plain list of annotation file paths (filename stem → ID).

    DataFrame

    Two columns: first = individual ID, second = annotation file.

    str

    Path to a Luna sample-list (tab-delimited ID / EDF / annot) or a glob pattern matching annotation files.

  • seed (str or list of str) – Annotation class(es) to use as seeds — the events whose enrichment is being tested.

  • other (str or list of str, optional) – Annotation class(es) to measure overlap against. Defaults to all annotations present other than the seeds.

  • bg (str or list of str, optional) – Background annotation class(es) defining the regions within which permutations are performed. Required unless event_perm=True.

  • nreps (int) – Number of permutations (default 1000).

  • event_perm (bool) – Use event-based permutation (shuffle seed positions) instead of background-region shuffling.

  • event_perm_w (float, optional) – Neighbourhood window in seconds for event permutation (default 5 s).

  • w (float, optional) – Window size in seconds for distance-based calculations.

  • out (str, optional) – Path for the output database. If omitted, a temporary file is used; the path is accessible via result.files[0].

  • luna_bin (str, optional) – Path to the luna binary. Defaults to searching PATH.

  • **kwargs – Any additional luna --overlap parameters, e.g. edges=5, pileup='T', seed_seed='T'.

Returns:

Output database reader. Use .tables() to list available outputs and .get('OVERLAP', r='SEED') to extract results.

Return type:

lp.destrat

Raises:
  • ValueError – If neither bg nor event_perm=True is provided.

  • FileNotFoundError – If no annotation files are found or luna is not on PATH.

Examples

>>> db = lp.overlap(
...     {'id1': 'id1.annot', 'id2': 'id2.annot'},
...     seed='spindle',
...     bg='NREM',
...     nreps=1000,
... )
>>> db.tables()
>>> db.get('OVERLAP', r='SEED')
>>> # from a sample list
>>> db = lp.overlap('cohort.lst', seed='spindle', bg='NREM', other='SO')
>>> # event permutation mode (no bg required)
>>> db = lp.overlap(files, seed='spindle', event_perm=True, nreps=500)