lunapi.edf_utils ================ .. py:module:: lunapi.edf_utils .. autoapi-nested-parse:: 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 --------- .. autoapisummary:: lunapi.edf_utils.merge_edfs lunapi.edf_utils.bind_edfs lunapi.edf_utils.overlap Module Contents --------------- .. py:function:: merge_edfs(files, edf='merged.edf', id='merged', slist=None, fixed=False, luna_bin=None) 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). :param files: EDF file paths to merge. :type files: list of str :param edf: Output EDF filename (default ``'merged.edf'``). :type edf: str :param id: EDF record ID for the merged file (default ``'merged'``). :type id: str :param slist: If given, write a one-row Luna sample-list to this path. :type slist: str, optional :param fixed: If ``True``, ignore file timestamps and concatenate in list order. :type fixed: bool :param luna_bin: Path to the ``luna`` binary. Defaults to searching PATH. :type luna_bin: str, optional :returns: Path to the written output EDF. :rtype: pathlib.Path .. rubric:: Examples >>> lp.merge_edfs(['night1.edf', 'night2.edf'], edf='both_nights.edf', id='subj1') PosixPath('both_nights.edf') .. py:function:: bind_edfs(files, edf='merged.edf', id='merged', slist=None, luna_bin=None) 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. :param files: EDF file paths to bind. :type files: list of str :param edf: Output EDF filename (default ``'merged.edf'``). :type edf: str :param id: EDF record ID for the bound file (default ``'merged'``). :type id: str :param slist: If given, write a one-row Luna sample-list to this path. :type slist: str, optional :param luna_bin: Path to the ``luna`` binary. Defaults to searching PATH. :type luna_bin: str, optional :returns: Path to the written output EDF. :rtype: pathlib.Path .. rubric:: Examples >>> lp.bind_edfs(['eeg.edf', 'eog.edf', 'emg.edf'], edf='psg.edf', id='subj1') PosixPath('psg.edf') .. py:function:: overlap(files, seed, other=None, bg=None, nreps=1000, event_perm=False, event_perm_w=None, w=None, out=None, luna_bin=None, **kwargs) 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. :param files: 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. :type files: dict, list, DataFrame, or str :param seed: Annotation class(es) to use as seeds — the events whose enrichment is being tested. :type seed: str or list of str :param other: Annotation class(es) to measure overlap against. Defaults to all annotations present other than the seeds. :type other: str or list of str, optional :param bg: Background annotation class(es) defining the regions within which permutations are performed. Required unless ``event_perm=True``. :type bg: str or list of str, optional :param nreps: Number of permutations (default 1000). :type nreps: int :param event_perm: Use event-based permutation (shuffle seed positions) instead of background-region shuffling. :type event_perm: bool :param event_perm_w: Neighbourhood window in seconds for event permutation (default 5 s). :type event_perm_w: float, optional :param w: Window size in seconds for distance-based calculations. :type w: float, optional :param out: Path for the output database. If omitted, a temporary file is used; the path is accessible via ``result.files[0]``. :type out: str, optional :param luna_bin: Path to the ``luna`` binary. Defaults to searching PATH. :type luna_bin: str, optional :param \*\*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. :rtype: lp.destrat :raises ValueError: If neither ``bg`` nor ``event_perm=True`` is provided. :raises FileNotFoundError: If no annotation files are found or ``luna`` is not on PATH. .. rubric:: 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)