Skip to content

analysis

Helpers for writing an analysis that runs on the platform.

An analysis reads a manifest, takes the channels it names, does its work and writes an events document. Two of those three already have a helper here (:func:~yousleep_common.utils.manifest.load_manifest and :func:~yousleep_common.utils.event_blocks.save_event_blocks). This module is the third, and it exists because getting it wrong is silent.

Nothing here is required. The contract is a JSON document and a file, and an analysis that reads them itself is a first-class citizen — in any language. These are the parts every Python analysis would otherwise write identically, offered one function at a time so a caller can take what helps and leave the rest.

ChannelMismatchError

Bases: ValueError

The recording is not the one the manifest describes.

SelectedChannel dataclass

One channel the manifest asked for, located in the file.

channel_for_slot(selected, slot)

Return the channel filling a named slot, or None.

An analysis whose configuration declares slots — a left and a right EOG, say — asks for them by label rather than guessing from order. Order is stable, but a configuration that gains a slot changes it, and a lookup that named the slot keeps working.

select_channels(manifest, header_labels)

Resolve the manifest's channels against a recording's header, and check them.

Channels are selected by index, never by label, and this function exists to make that the easy thing to do rather than the thing you remember. The manifest gives each channel an index, the position of the signal in the file; a source_name, the label the header carries at that position; and a name, what the user calls it, which is what belongs in your output.

A recording may repeat a label and a user may rename a channel, so an analysis that matches on a name can read a different signal than the one the platform selected — and it will do so quietly, producing plausible results for the wrong data. This checks that the label at each index is the one the manifest names and raises if it is not, which is the failure you want: loud, before any signal is read.

Parameters:

Name Type Description Default
manifest AnalysisManifest

The manifest the platform wrote for this run.

required
header_labels list[str]

The recording's channel labels, in file order. Every reader offers these — mne.io.read_raw_edf(...).ch_names, pyedflib.EdfReader(...).getSignalLabels().

required

Returns:

Name Type Description
One list[SelectedChannel]

class:SelectedChannel per channel the manifest asked for, in

list[SelectedChannel]

the manifest's order.

Raises:

Type Description
ChannelMismatchError

An index is out of range for this file, or the label there is not the one the manifest names. Either means the recording is not the one the manifest describes.

Example

raw = mne.io.read_raw_edf(manifest.inputs.recording.path) # doctest: +SKIP selected = select_channels(manifest, header_labels=raw.ch_names) # doctest: +SKIP raw.pick([channel.index for channel in selected]) # doctest: +SKIP