Usage
This page walks through the full Pyxations pipeline: from raw eye-tracking recordings to per-trial fixations and saccades ready for analysis.
The pipeline has three stages:
- Convert raw recordings into a BIDS-formatted dataset.
- Compute derivatives: parse files, detect eye movements, split into trials.
- Analyze and visualize the resulting data.
1. Convert raw recordings to BIDS
dataset_to_bids takes a folder of raw recordings and produces a BIDS-compliant dataset.
import pyxations as pyx
pyx.dataset_to_bids(
target_folder_path="path/to/output", # where the BIDS dataset will be created
files_folder_path="path/to/raw/edf/files", # folder containing raw recordings
dataset_name="my_experiment",
)
The resulting layout looks like:
path/to/output/my_experiment/
├── participants.tsv # maps new sub-XXXX IDs to your original IDs
├── sub-0001/
│ └── ses-<session>/
│ └── ET/
│ └── <original_filename>.edf
├── sub-0002/
│ └── ses-<session>/
│ └── ET/
└── ...
Subject IDs are inferred from the source filenames (everything before the first _) and re-numbered as zero-padded sub-0001, sub-0002, … The mapping to your original IDs is preserved in participants.tsv. The session label comes from the next part of the filename: use session_substrings=N to take more underscore-separated tokens.
2. Compute derivatives
Derivatives are the parsed, processed outputs of the pipeline: messages, samples, detected fixations and saccades, split into trials. They are stored in a sibling *_derivatives/ folder next to the BIDS dataset, preserving the same subject layout.
pyx.compute_derivatives_for_dataset(
bids_dataset_folder="path/to/output/my_experiment",
dataset_format="eyelink", # "eyelink" | "tobii" | "gaze" | "webgazer"
detection_algorithm="remodnav", # "remodnav" | "engbert"
msg_keywords=["begin", "end", "press"],
start_msgs={"search": ["beginning_of_stimuli"]},
end_msgs={"search": ["end_of_stimuli"]},
overwrite=True,
)
Trial segmentation parameters
msg_keywords: substrings used to filter which experimenter messages from the recording are kept in the parsed output. Anything not matching is discarded to keep the message table small.start_msgs/end_msgs: define how each trial is delimited based on messages logged during the recording.
Pyxations accepts one of three segmentation strategies, picked by which kwargs you pass:
start_msgs+end_msgs: trials run from a start message to an end message.start_msgs+durations: fixed-duration trials anchored at each start message.start_times+end_times: explicit per-trial timestamps (typically loaded from a behavioral log).
See pyxations.pre_processing for the full segmentation API.
Detection algorithms
remodnav: wraps the REMoDNaV package.engbert: Python port ofdetecteyemovements.mfrom the EYE-EEG toolbox.
See pyxations.methods.eyemovement for parameters specific to each algorithm.
3. Load and analyze derivatives
Once derivatives exist, the high-level Experiment API gives access to per-subject, per-session, per-trial data. Point it at the BIDS dataset path (not the derivatives folder); the sibling *_derivatives/ is found automatically.
from pyxations import Experiment
exp = Experiment(dataset_path="path/to/output/my_experiment")
exp.load_data("remodnav") # must match the detection_algorithm you computed
for subject_id, subject in exp.subjects.items():
for session_id, session in subject.sessions.items():
fixations = session.fixations() # polars.DataFrame
saccades = session.saccades() # polars.DataFrame
samples = session.samples() # polars.DataFrame (raw gaze)
# Access a specific trial
trial = exp.get_trial(subject_id="0001", session_id="second", trial_number=0)
trial.fixations()
trial.saccades()
exp.subjects and subject.sessions are dicts keyed by ID strings ("0001", …). Tables are returned as polars DataFrames.
For visual-search paradigms, VisualSearchExperiment adds helpers for target/distractor analyses.
4. Visualization
Each Trial knows how to plot itself:
trial.plot_scanpath(screen_height=1080, screen_width=1920)
trial.plot_animation(screen_height=1080, screen_width=1920)
For aggregate plots across a session or experiment, use the Visualization class directly:
from pyxations import Visualization
vis = Visualization(
derivatives_folder_path=exp.derivatives_path,
events_detection_algorithm="remodnav",
)
vis.fix_duration(session.fixations())
vis.sacc_amplitude(session.saccades())
vis.sacc_main_sequence(session.saccades())
See pyxations.visualization for the full plot catalog.
Worked examples
The repository includes runnable notebooks under notebooks/:
Eyelink tutorial.ipynb: full EyeLink pipeline on the bundled example dataset.multimatch_example.ipynb: scanpath comparison with MultiMatch.webgazer_example.ipynb: webcam-based recordings.driving_animation.ipynb: visualization on a continuous task.
A small example_dataset/ is also included to reproduce the tutorial end-to-end.