Note
Go to the end to download the full example code.
Events¶
In neuralset, everything is an event: a word displayed on screen,
an MEG recording, an fMRI scan, a button press — each is represented
as an Event with a position in time.
Events are the common representation that connects data sources (studies) to the features you extract from them (extractors). A study produces an events DataFrame; extractors read it to know what to extract and when.
What is an Event?¶
An event has three core fields: start (seconds), duration
(seconds), and timeline (which recording session it belongs to).
Concrete subclasses add modality-specific fields — for example a
Word carries text:
from neuralset.events import etypes
word = etypes.Word(start=1.5, duration=0.3, timeline="sub-01_run-01", text="hello")
print(repr(word))
Word(**
{ 'context': '',
'duration': 0.3,
'extra': {},
'language': '',
'modality': None,
'sentence': '',
'sentence_char': None,
'start': 1.5,
'text': 'hello',
'timeline': 'sub-01_run-01'}
)
Timelines¶
A timeline identifies one continuous time axis —
typically one recording run for one subject (e.g. "sub-01_run-02").
Events that share a timeline share a clock: start=1.5 in one event
and start=2.0 in another mean they are 0.5 s apart.
A single events DataFrame can hold many timelines (subjects, runs, sessions). Downstream processing (extractors, segmenters) groups by timeline automatically, so you rarely need to split manually.
The Events DataFrame¶
The standard way to work with events is a pandas DataFrame where
each row is one event. This is what Study.run() produces, but you can also
build one by hand:
import pandas as pd
from neuralset import events
tl = "sub-01_run-01"
rows = [
dict(type="Word", start=10.5, duration=0.3, timeline=tl, text="The"),
dict(type="Word", start=11.0, duration=0.4, timeline=tl, text="cat"),
dict(type="Word", start=11.6, duration=0.3, timeline=tl, text="sat"),
dict(type="Sentence", start=10.5, duration=1.4, timeline=tl, text="The cat sat"),
]
df = events.standardize_events(pd.DataFrame(rows))
print(df[["type", "start", "duration", "timeline"]].to_string())
type start duration timeline
0 Sentence 10.5 1.4 sub-01_run-01
1 Word 10.5 0.3 sub-01_run-01
2 Word 11.0 0.4 sub-01_run-01
3 Word 11.6 0.3 sub-01_run-01
standardize_events() validates types, checks
required fields, and sorts by timeline and start time.
Filtering by type is plain pandas:
words = df[df.type == "Word"]
print(f"{len(words)} word events")
3 word events
Event Types¶
neuralset ships with many event subclasses covering neural recordings,
stimuli, text, and annotations. The hierarchy lets you filter by a
parent class to match all its children (e.g. filtering for MneRaw
matches Meg, Eeg, Ieeg, etc.).
Event
├── BaseDataEvent # events backed by a file
│ ├── BaseSplittableEvent # audio/video/neuro with partial loading
│ │ ├── Audio # WAV audio files
│ │ ├── Video # video files
│ │ ├── MneRaw # brain recordings (MNE format)
│ │ │ ├── Meg, Eeg, Emg # magneto/electro-encephalography, electromyography
│ │ │ ├── Ieeg # intracranial EEG (sEEG, ECoG)
│ │ │ └── Fnirs # functional near-infrared spectroscopy
│ │ └── Fmri # functional MRI (NIfTI)
│ ├── Image # image files (PIL) with optional caption
│ └── Spikes # spike-sorted neural data
├── BaseText # text-based events
│ ├── Text, Sentence, Word # from paragraph to single word
│ ├── Phoneme # single phoneme
│ └── Keystroke # keystroke with text label
├── CategoricalEvent # discrete labels / categories
│ ├── Action # motor execution or imagination
│ ├── Stimulus # trigger code
│ ├── EyeState # eyes open / closed
│ ├── Artifact, Seizure, ... # clinical annotations
│ └── SleepStage # W, N1, N2, N3, R
print("Registered event types:", sorted(etypes.Event._CLASSES.keys()))
Registered event types: ['Action', 'Artifact', 'Audio', 'Background', 'BaseDataEvent', 'BaseSplittableEvent', 'BaseText', 'CategoricalEvent', 'Eeg', 'Emg', 'Event', 'EyeState', 'Fmri', 'Fnirs', 'Ieeg', 'Image', 'Keystroke', 'Meg', 'MneRaw', 'Phoneme', 'Seizure', 'Sentence', 'SleepStage', 'Spikes', 'Stimulus', 'Text', 'Video', 'Word', '_VideoImage']
Creating Events from Dicts¶
Event.from_dict()
dispatches to the right subclass based on the type field.
Fields not in the subclass schema are stored in
extra:
data = {
"type": "Word",
"start": 1.0,
"timeline": "run-01",
"text": "hello",
"surprisal": 3.2,
}
event = etypes.Event.from_dict(data)
print(f"class: {type(event).__name__}, extra: {event.extra}")
class: Word, extra: {'surprisal': 3.2}
to_dict() flattens back to a plain dict
(extra fields become top-level keys):
print(event.to_dict())
{'surprisal': 3.2, 'type': 'Word', 'start': 1.0, 'timeline': 'run-01', 'duration': 0.0, 'text': 'hello', 'language': '', 'context': '', 'modality': None, 'sentence': '', 'sentence_char': None}
Next Steps¶
Learn how studies produce events: Studies
Modify events with transforms: Transforms
Total running time of the script: (0 minutes 0.012 seconds)