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 — |
required |
Returns:
| Name | Type | Description |
|---|---|---|
One |
list[SelectedChannel]
|
class: |
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