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:
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', 'SleepOnsetMarker', '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.039 seconds)