API documentation

Python-package to help with processing of pupillometric and eyetracking data.

This package provides classes for handling pupillometric and eyetracking data as well as tools for plotting and analyzing these data.

Unit Handling:

Distance and angle parameters accept three formats: 1. Plain numbers (assumed to be mm for distances, radians for angles - with warning) 2. String format: “600 mm”, “60 cm”, “20 degrees”, “-90 degrees” 3. Pint Quantity: 600 * ureg.mm, 20 * ureg.degree

The unit registry is available as pypillometry.ureg for advanced users.

Overview

        classDiagram
 EyeData <|-- GazeData
 EyeData <|-- PupilData
 PupilData <|-- GenericEyeData
 GazeData <|-- GenericEyeData

 GazeData: +EyeDataDict data[left_x, left_y, right_x, right_y]
 GazeData: +GazePlotter plot
 GazeData: +set_experimental_setup() (and other gaze-specific functions)
 PupilData: +EyeDataDict data[left_pupil, right_pupil]
 PupilData: +PupilPlotter plot
 PupilData: +pupil_blinks_detect() (and other pupil-specific functions)
 EyeData: +EyeDataDict data[left_pupil, right_pupil, left_x, left_y, right_x, right_y]
 EyeData: +EyePlotter plot
 EyeData: +correct_pupil_foreshortening() (and other functions needing both gaze and pupil data)
    

EyeData([time, left_x, left_y, left_pupil, ...])

Class for handling eye-tracking data.

PupilData([time, left_pupil, right_pupil, ...])

Class representing pupillometric data.

GazeData([time, left_x, left_y, right_x, ...])

Class representing Eye-Tracking data (x,y) from one or two eyes.

GenericEyeData()

Generic class for eyedata.

EyeDataDict(*args, **kwargs)

A dictionary that contains 1-dimensional ndarrays of equal length and with the same datatype (float).

Primary classes

Several different classes are available for handling different types of eye data.

  • PupilData: If you have only pupillometric data, use this class.

  • GazeData: If you only have gaze data, use this class.

  • EyeData: If you have both gaze and pupillometric data, use this class.

These classes inherit from GenericEyeData, which provides some basic, shared functionality for handling eye data.

The data inside each of these classes is stored in the data attribute, which is a dictionary-like object of type EyeDataDict.

Each of these classes provides access to a matching plotter object (from module pypillometry.plot) that is stored in the plot attribute.

EyeData

class pypillometry.EyeData(time=None, left_x=None, left_y=None, left_pupil=None, right_x=None, right_y=None, right_pupil=None, event_onsets=None, event_labels=None, sampling_rate=None, experimental_setup=None, name=None, calibration=None, fill_time_discontinuities=True, keep_orig=False, info=None, inplace=False)[source]

Class for handling eye-tracking data. This class is a subclass of GazeData and inherits all its methods and attributes. In addition to the methods in GazeData which implement functions for eye-tracking data, EyeData provides methods for handling pupillometric data.

Parameters:
  • time (ndarray) – timing array or None, in which case the time-array goes from [0,maxT] using sampling_rate (in ms)

  • left_x (ndarray) – data from left eye (at least one of the eyes must be provided, both x and y) pupil is optional

  • left_y (ndarray) – data from left eye (at least one of the eyes must be provided, both x and y) pupil is optional

  • left_pupil (ndarray) – data from left eye (at least one of the eyes must be provided, both x and y) pupil is optional

  • right_x (ndarray) – data from right eye (at least one of the eyes must be provided, both x and y) pupil is optional

  • right_y (ndarray) – data from right eye (at least one of the eyes must be provided, both x and y) pupil is optional

  • right_pupil (ndarray) – data from right eye (at least one of the eyes must be provided, both x and y) pupil is optional

  • sampling_rate (float) – sampling-rate of the pupillary signal in Hz; if None,

  • experimental_setup (ExperimentalSetup, optional) – Geometric model of the experimental setup including screen geometry, eye position, camera position, and screen orientation.

  • name (str) – name of the dataset or None (in which case a random string is selected)

  • event_onsets (ndarray) – time-onsets of any events in the data (in ms, matched in time vector)

  • event_labels (ndarray) – for each event in event_onsets, provide a label

  • calibration (dict, optional) – Dictionary of SpatialCalibration objects, one per eye (keys: ‘left’, ‘right’)

  • keep_orig (bool) – keep a copy of the original dataset? If True, a copy of the object as initiated in the constructor is stored in member original

  • fill_time_discontinuities (bool) – sometimes, when the eyetracker loses signal, no entry in the EDF is made; when this option is True, such entries will be made and the signal set to 0 there (or do it later using fill_time_discontinuities())

Examples

>>> import numpy as np
>>> from pypillometry.eyedata import EyeData
>>> d=EyeData(time=np.arange(0, 1000, 1),
...         left_x=np.random.randn(1000),
...         left_y=np.random.randn(1000))
>>> print(d)
Attributes:
blinks

Return blinks (intervals) for all eyes.

eyes

Return a list of available eyes in the dataset.

plot
variables

Return a list of available variables in the dataset.

Methods

add_to_history(event)

Add event to history

apply_history(obj)

Apply history of operations done on self to obj.

blink_stats([eyes, units])

Return statistics on blink durations.

blinks_merge_close([eyes, variables, ...])

Merge blinks that are close together.

copy([new_name])

Make and return a deep-copy of the pupil data.

correct_pupil_foreshortening([eyes, ...])

Correct pupil data using a simple algorithm to correct for foreshortening effects.

downsample(fsd[, dsfac, inplace])

Simple downsampling scheme using mean within the downsampling window.

drop_original([inplace])

Drop original dataset from record (e.g., to save space).

fill_time_discontinuities([yval, print_info])

find gaps in the time-vector and fill them in (add zeros to the signal)

fit_foreshortening(eye[, r, d, intervals, ...])

Fit foreshortening correction model to estimate camera geometry and true pupil size.

from_eyelink(fname[, return_edf_obj, ...])

Reads a GenericEyedata object from an Eyelink file.

from_file(fname)

Reads a GenericEyedata object from a pickle-file.

get_blinks([eyes, variables, units])

Get blinks as Intervals object or dict of Intervals.

get_duration([units])

Return duration of the dataset in units specified.

get_erpd(intervals[, eyes, variable, ...])

Extract event-related pupil dilation (ERPD) from Intervals object.

get_events([units])

Get events as an Events object.

get_interpolated_blinks([eyes, variables, units])

Get interpolated blinks as Intervals object or dict of Intervals.

get_intervals(event_select[, interval, ...])

Return an Intervals object containing intervals relative to event-onsets.

get_pupildata([eye])

Return the pupil data as a PupilData object.

get_size()

Return the size of the object in bytes.

interpolate_intervals(intervals[, eyes, ...])

Interpolate data within specified intervals.

mask_as_intervals([eyes, variables, units, ...])

Convert masks to Intervals objects.

mask_eye_divergences([threshold, thr_type, ...])

Calculate Euclidean distance between left and right eye coordinates and detect divergences.

mask_intervals(intervals[, eyes, variables, ...])

Apply Intervals as masks to selected data.

mask_offscreen_coords([eyes, apply_mask, ...])

Detect and mask gaze coordinates that fall outside the screen boundaries.

merge_eyes([eyes, variables, method, ...])

Merge data from both eyes into a single variable.

merge_masks([inplace])

Merge masks of all variables into a single joint mask.

nblinks([eyes, variables])

Return number of detected blinks.

nevents()

Return number of events in data.

print_history()

Pretty-print the history of the current dataset (which manipulations where done on it).

pupil_blinks_detect([eyes, min_duration, ...])

Detect blinks in the pupillary signal using several strategies.

pupil_blinks_interpolate([eyes, store_as, ...])

Interpolating blinks in the pupillary signal.

pupil_estimate_baseline([eyes, variable, ...])

Apply one of the baseline-estimation methods.

pupil_estimate_response([eyes, npar, tmax, ...])

Estimate pupil-response based on event-onsets, see pypillometry.pupil.pupil_response().

pupil_lowpass_filter(cutoff[, order, eyes, ...])

Lowpass-filter pupil signal using a Butterworth-filter, see baseline.butter_lowpass_filter().

pupil_smooth_window([eyes, window, winsize, ...])

Apply smoothing of the signal using a moving window.

reset_time([t0, inplace])

Resets time so that the time-array starts at time zero (t0).

scale([variables, mean, sd, eyes, inplace])

Scale the signal by subtracting mean and dividing by sd.

set_blinks(intervals[, eyes, variables, ...])

Set blinks for specified eyes and variables.

set_event_onsets(event_onsets, event_labels)

Set onsets of events in the data

set_events(events[, inplace])

Replace event onsets and labels from an Events object.

set_experimental_setup(**kwargs)

Set or update the experimental setup geometry.

stat_per_event([intervals, interval, ...])

Return result of applying a statistical function to data in a given interval relative to event-onsets.

sub_slice([start, end, units, inplace])

Return a new EyeData object that is a shortened version of the current one (contains all data between start and end in units given by units (one of "ms", "sec", "min", "h").

summary()

Return a summary of the dataset as a dictionary.

unscale([variables, mean, sd, eyes, inplace])

Scale back to original values using either values provided as arguments or the values stored in scale_params.

write_file(fname)

Save to file (using pickle).

correct_pupil_foreshortening(eyes=[], midpoint=None, store_as='pupil', inplace=None)[source]

Correct pupil data using a simple algorithm to correct for foreshortening effects.

Correct the pupil data for foreshortening effects caused by saccades/eye movements. This method is based on a simple algorithm described here:

Correcting pupillary signal using a simple Foreshortening Algorithm

Relevant publication (not the description of the algorithm used here): https://link.springer.com/article/10.3758/s13428-015-0588-x

  • [ ] TODO: when using interpolated pupil data, x/y data may still be missing. Make sure that the pupil data is not touched where x/y is missing

Parameters:
  • eyes (list) – Which eyes to correct. If None, correct all available eyes.

  • midpoint (tuple) – The center of the screen (x,y) where it is assumed that the pupil is completely circular. If None, the midpoint is taken to be the center of the screen as registered in the experimental_setup.

  • inplace (bool) – Whether to modify the object in place or return a new object. true: modify in place false: return a new object None: use the object’s default setting (initialized in __init__)

Returns:

An EyeData object with the corrected pupil

Return type:

EyeData

fit_foreshortening(eye, r=None, d=None, intervals=None, target_fs=50.0, lowpass_freq=4.0, lambda_smooth=1.0, knots_per_second=1.0, initial_theta=None, initial_phi=None, verbose=True)[source]

Fit foreshortening correction model to estimate camera geometry and true pupil size.

This method implements Stage 1 of the foreshortening correction algorithm, which jointly estimates the camera position (theta, phi) and the temporal dynamics of true pupil size A0(t) using B-splines. The data is automatically preprocessed (filtered and downsampled) before fitting.

Parameters:
  • eye (str) – Which eye to fit (‘left’ or ‘right’)

  • r (float, str, or pint.Quantity, optional) – Eye-to-camera distance. If not provided, uses the r from experimental_setup. - Plain number: assumed to be mm (with warning) - String: e.g., “600 mm”, “60 cm” - Quantity: e.g., 600 * ureg.mm

  • d (float, str, or pint.Quantity, optional) – Eye-to-screen distance. If not provided, uses the d from experimental_setup. - Plain number: assumed to be mm (with warning) - String: e.g., “700 mm”, “70 cm” - Quantity: e.g., 700 * ureg.mm

  • intervals (Intervals, optional) – Time intervals to use for fitting. If None, uses all available data. Useful for fitting only on calibration periods.

  • target_fs (float, default 50.0) – Target sampling rate in Hz after downsampling for efficiency. Pupil dynamics are typically well-preserved at 50 Hz.

  • lowpass_freq (float, default 4.0) – Lowpass filter cutoff frequency in Hz. Removes high-frequency noise before downsampling. Should be below target_fs/2 (Nyquist).

  • lambda_smooth (float, default 1.0) – Smoothness regularization weight. Higher values produce smoother A0(t) estimates. Tune via cross-validation if needed.

  • knots_per_second (float, default 1.0) – Number of B-spline knots per second. Controls temporal resolution of A0(t) model. Typical values: 0.5-2.0.

  • initial_theta (float, str, or pint.Quantity, optional) – Initial guess for camera polar angle. If None, uses pi/2 (horizontal) as starting point. - Plain number: assumed to be radians (with warning) - String: e.g., “20 degrees”, “0.349 radians” - Quantity: e.g., 20 * ureg.degree

  • initial_phi (float, str, or pint.Quantity, optional) – Initial guess for camera azimuthal angle. If None, uses 0 (camera on x-axis) as starting point. - Plain number: assumed to be radians (with warning) - String: e.g., “-90 degrees”, “-1.57 radians” - Quantity: e.g., -90 * ureg.degree

  • verbose (bool, default True) – Print optimization progress and fit statistics.

Returns:

calibration – Fitted calibration object containing camera geometry (theta, phi), spline coefficients for A0(t), and fit quality metrics.

Return type:

ForeshorteningCalibration

Raises:

ValueError – If specified eye doesn’t exist or lacks gaze/pupil data.

Notes

The model is:

A_measured(x,y,t) = A0(t) * cos(alpha(x,y; theta, phi))

where: - A0(t) = sum_k a_k * B_k(t) is modeled with B-splines - cos(alpha) is the foreshortening factor depending on viewing angle - theta, phi parameterize camera position in spherical coordinates

The optimization minimizes:

sum_i (A_i - A_pred_i)^2 + lambda_smooth * sum_k (a_{k+1} - a_k)^2

Examples

>>> import pypillometry as pp
>>> data = pp.EyeData.from_eyelink('recording.edf')
>>>
>>> # Set experimental setup
>>> data.set_experimental_setup(
...     screen_resolution=(1920, 1080),
...     physical_screen_size=("52 cm", "29 cm"),
...     eye_to_screen_center="65 cm",
...     camera_offset=("0 cm", "-30 cm", "0 cm"),
... )
>>>
>>> # Fit on calibration period (first 2 minutes)
>>> cal_intervals = data.get_intervals(end_time=120000)
>>> calib = data.fit_foreshortening(
...     eye='left',
...     intervals=cal_intervals
... )
>>>
>>> # Or provide r and d explicitly
>>> calib = data.fit_foreshortening(
...     eye='left',
...     r="60 cm",
...     d="70 cm",
...     intervals=cal_intervals
... )
>>>
>>> # Inspect fit quality
>>> print(calib)
>>> print(f"R² = {calib.fit_metrics['r2']:.3f}")
>>>
>>> # Compute correction for all data
>>> correction_factor = calib.get_correction_factor(
...     data['left', 'x'],
...     data['left', 'y']
... )
>>> corrected_pupil = data['left', 'pupil'] * correction_factor

See also

ForeshorteningCalibration

Container for fitted parameters

correct_pupil_foreshortening

Simple foreshortening correction method

get_pupildata(eye=None)[source]

Return the pupil data as a PupilData object.

Parameters:

eye (str, optional) – Which eye to return data for.

Returns:

A PupilData object containing the pupil data.

Return type:

PupilData

summary()[source]

Return a summary of the dataset as a dictionary.

Returns:

A dictionary summarizing the dataset.

Return type:

dict

PupilData

class pypillometry.PupilData(time=None, left_pupil=None, right_pupil=None, event_onsets=None, event_labels=None, sampling_rate=None, name=None, fill_time_discontinuities=True, keep_orig=False, info=None, inplace=False)[source]

Class representing pupillometric data.

The class is a subclass of GenericEyedata and inherits all its methods.

If eye-tracking data is available in addition to pupillometry, use the EyeData class.

Parameters:
  • time (ndarray) – timing array or None, in which case the time-array goes from [0,maxT] using sampling_rate (in ms)

  • left_pupil (ndarray) – data from left eye (at least one of the eyes must be provided)

  • right_pupil (ndarray) – data from right eye (at least one of the eyes must be provided)

  • sampling_rate (float) – sampling-rate of the signal in Hz; if None,

  • name (str) – name of the dataset or None (in which case a random string is selected)

  • event_onsets (ndarray) – time-onsets of any events in the data (in ms, matched in time vector)

  • event_labels (ndarray) – for each event in event_onsets, provide a label

  • keep_orig (bool) – keep a copy of the original dataset? If True, a copy of the object as initiated in the constructor is stored in member original

  • fill_time_discontinuities (bool) – sometimes, when the eyetracker loses signal, no entry in the EDF is made; when this option is True, such entries will be made and the signal set to 0 there (or do it later using fill_time_discontinuities())

  • inplace (bool) – if True, the object is modified in place; if False, a new object is returned this object-level property can be overwritten by the method-level inplace argument default is “False”

Attributes:
blinks

Return blinks (intervals) for all eyes.

eyes

Return a list of available eyes in the dataset.

plot
variables

Return a list of available variables in the dataset.

Methods

add_to_history(event)

Add event to history

apply_history(obj)

Apply history of operations done on self to obj.

blink_stats([eyes, units])

Return statistics on blink durations.

blinks_merge_close([eyes, variables, ...])

Merge blinks that are close together.

copy([new_name])

Make and return a deep-copy of the pupil data.

downsample(fsd[, dsfac, inplace])

Simple downsampling scheme using mean within the downsampling window.

drop_original([inplace])

Drop original dataset from record (e.g., to save space).

fill_time_discontinuities([yval, print_info])

find gaps in the time-vector and fill them in (add zeros to the signal)

from_eyelink(fname[, return_edf_obj, ...])

Reads a GenericEyedata object from an Eyelink file.

from_file(fname)

Reads a GenericEyedata object from a pickle-file.

get_blinks([eyes, variables, units])

Get blinks as Intervals object or dict of Intervals.

get_duration([units])

Return duration of the dataset in units specified.

get_erpd(intervals[, eyes, variable, ...])

Extract event-related pupil dilation (ERPD) from Intervals object.

get_events([units])

Get events as an Events object.

get_interpolated_blinks([eyes, variables, units])

Get interpolated blinks as Intervals object or dict of Intervals.

get_intervals(event_select[, interval, ...])

Return an Intervals object containing intervals relative to event-onsets.

get_size()

Return the size of the object in bytes.

interpolate_intervals(intervals[, eyes, ...])

Interpolate data within specified intervals.

mask_as_intervals([eyes, variables, units, ...])

Convert masks to Intervals objects.

mask_intervals(intervals[, eyes, variables, ...])

Apply Intervals as masks to selected data.

merge_eyes([eyes, variables, method, ...])

Merge data from both eyes into a single variable.

merge_masks([inplace])

Merge masks of all variables into a single joint mask.

nblinks([eyes, variables])

Return number of detected blinks.

nevents()

Return number of events in data.

print_history()

Pretty-print the history of the current dataset (which manipulations where done on it).

pupil_blinks_detect([eyes, min_duration, ...])

Detect blinks in the pupillary signal using several strategies.

pupil_blinks_interpolate([eyes, store_as, ...])

Interpolating blinks in the pupillary signal.

pupil_estimate_baseline([eyes, variable, ...])

Apply one of the baseline-estimation methods.

pupil_estimate_response([eyes, npar, tmax, ...])

Estimate pupil-response based on event-onsets, see pypillometry.pupil.pupil_response().

pupil_lowpass_filter(cutoff[, order, eyes, ...])

Lowpass-filter pupil signal using a Butterworth-filter, see baseline.butter_lowpass_filter().

pupil_smooth_window([eyes, window, winsize, ...])

Apply smoothing of the signal using a moving window.

reset_time([t0, inplace])

Resets time so that the time-array starts at time zero (t0).

scale([variables, mean, sd, eyes, inplace])

Scale the signal by subtracting mean and dividing by sd.

set_blinks(intervals[, eyes, variables, ...])

Set blinks for specified eyes and variables.

set_event_onsets(event_onsets, event_labels)

Set onsets of events in the data

set_events(events[, inplace])

Replace event onsets and labels from an Events object.

stat_per_event([intervals, interval, ...])

Return result of applying a statistical function to data in a given interval relative to event-onsets.

sub_slice([start, end, units, inplace])

Return a new EyeData object that is a shortened version of the current one (contains all data between start and end in units given by units (one of "ms", "sec", "min", "h").

summary()

Return a summary of the dataset as a dictionary.

unscale([variables, mean, sd, eyes, inplace])

Scale back to original values using either values provided as arguments or the values stored in scale_params.

write_file(fname)

Save to file (using pickle).

get_erpd(intervals, eyes=[], variable='pupil', baseline_win=None)[source]

Extract event-related pupil dilation (ERPD) from Intervals object. No attempt is being made to exclude overlaps of the time-windows.

Parameters:
  • intervals (Intervals) – Intervals object containing the time windows to extract (from get_intervals())

  • eyes (list or str) – str or list of eyes to process; if empty, all available eyes are processed

  • variable (str) – default is to use the “pupil” but it could be used to process, e.g., interpolated pupil data stored in a different variables, e.g., “pupilinterp”

  • baseline_win (tuple (float,float) or None) –

    if None, no baseline-correction is applied if tuple, the mean value in the window in milliseconds (relative to interval) is

    subtracted from the single-trial ERPDs (baseline-correction)

Detect blinks in the pupillary signal using several strategies. First, blinks are detected as consecutive sequence of blink_val (f.eks., 0 or NaN). Second, blinks are defined as everything between two crossings of the velocity profile (from negative to positive).

Detected blinks are always stored internally. When apply_mask=True, the blinks are also applied as masks to the data. When apply_mask=False, the detected blinks are returned as Intervals objects.

Finally, detected blinks have to be at least min_duration ms.

Parameters:
  • eyes (list) – list of eyes to process; if empty, all available eyes are processed

  • min_duration (float) – minimum duration in ms for a sequence of missing numbers to be treated as blink

  • blink_val (float) – “missing value” code

  • winsize (float) – window-size for Savitzky-Golay velocity estimation in ms

  • vel_onset (float or str) – velocity threshold to detect blink onset (negative value). - If float: threshold in pupil-units per millisecond (e.g., -5.0) - If str: percentile of velocity distribution (e.g., “5%” for bottom 5%)

  • vel_offset (float or str) – velocity threshold to detect blink offset (positive value). - If float: threshold in pupil-units per millisecond (e.g., 5.0) - If str: percentile of velocity distribution (e.g., “95%” for top 95%)

  • vel_onset_min_duration (float) – minimum duration in ms that velocity must exceed threshold to detect as onset (to avoid noise-induced false detections)

  • vel_offset_min_duration (float) – minimum duration in ms that velocity must exceed threshold to detect as offset (to avoid noise-induced false detections)

  • strategies (list of strategies to use) – so far, use a list containing any combination of “zero” and “velocity”

  • apply_mask (bool) – if True, apply detected blinks as masks to the data and return self if False (default), return detected blinks as Intervals (or dict of Intervals)

  • ignore_existing_mask (bool) – if True (default), use raw data ignoring existing masks if False, only detect blinks in non-masked data (already masked regions are skipped)

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes

Returns:

If apply_mask=True: returns self for chaining If apply_mask=False and single eye: returns Intervals object If apply_mask=False and multiple eyes: returns dict of Intervals objects

Return type:

self or Intervals or dict

Interpolating blinks in the pupillary signal.

Implements the blink-interpolation method by Mahot (2013).

Mahot, 2013: https://figshare.com/articles/A_simple_way_to_reconstruct_pupil_size_during_eye_blinks/688001.

This procedure relies heavily on eye-balling (reconstructing visually convincing signal), so a “plot” option is provided that will plot many diagnostics (see paper linked above) that can help to set good parameter values for winsize, vel_onset, vel_offset and margin.

Parameters:
  • eyes (str or list) – str or list of eyes to process; if empty, all available eyes are processed

  • store_as (str) – how to store the interpolated data; either “pupil” (default) which replaces the original pupil data or a string that will be used as the new variable name in the data (e.g., “pupilinterp”)

  • method (str) – method to use; so far, only “mahot” is implemented

  • winsize (float) – size of the Savitzky-Golay window in ms

  • vel_onset (float or str) – velocity threshold to detect blink onset (negative value). - If float: threshold in pupil-units per millisecond (e.g., -5.0) - If str: percentile of velocity distribution (e.g., “5%” for bottom 5%)

  • vel_offset (float or str) – velocity threshold to detect blink offset (positive value). - If float: threshold in pupil-units per millisecond (e.g., 5.0) - If str: percentile of velocity distribution (e.g., “95%” for top 95%)

  • margin (Tuple[float,float]) – margin that is subtracted/added to onset and offset (in ms)

  • blinkwindow (float) – how much time before and after each blink to include (in ms)

  • interp_type (str) – type of interpolation accepted by scipy.interpolate.interp1d()

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes

pupil_estimate_baseline(eyes=[], variable='pupil', method='envelope_iter_bspline_2', inplace=None, **kwargs)[source]

Apply one of the baseline-estimation methods.

Parameters:
  • eyes (list or str) – str or list of eyes to process; if empty, all available eyes are processed

  • variable (str) – default is to use the “pupil” but it could be used to process, e.g., interpolated pupil data stored in a different variables, e.g., “pupilinterp”

  • method (str) –

    “envelope_iter_bspline_1”: pypillometry.baseline.baseline_envelope_iter_bspline()

    with one iteration

    ”envelope_iter_bspline_2”: pypillometry.baseline.baseline_envelope_iter_bspline()

    with two iterations

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes

  • kwargs – named arguments passed to the low-level function in pypillometry.baseline.

Returns:

object with baseline estimated (stored in data[“eye_baseline”])

Return type:

PupilData

pupil_estimate_response(eyes=[], npar='free', tmax='free', verbose=50, bounds={'npar': (1, 20), 'tmax': (100, 2000)}, inplace=None)[source]

Estimate pupil-response based on event-onsets, see pypillometry.pupil.pupil_response().

Parameters:
  • eyes (list or str) – str or list of eyes to process; if empty, all available eyes are processed

  • npar (float) – npar-parameter for the canonical response-function or “free”; in case of “free”, the function optimizes for this parameter

  • tmax (float) – tmax-parameter for the canonical response-function or “free”; in case of “free”, the function optimizes for this parameter

  • bounds (dict) – in case that one or both parameters are estimated, give the lower and upper bounds for the parameters

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes

Note

the results of the estimation is stored in members response, response_x (design matrix) and response_pars

pupil_lowpass_filter(cutoff, order=2, eyes=[], inplace=None)[source]

Lowpass-filter pupil signal using a Butterworth-filter, see baseline.butter_lowpass_filter().

Parameters:
  • cutoff (float) – lowpass-filter cutoff

  • order (int) – filter order

  • eyes (list) – list of eyes to filter; if empty, all available eyes are filtered

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes if None, use the object-level setting

pupil_smooth_window(eyes=[], window='hanning', winsize=11, inplace=None)[source]

Apply smoothing of the signal using a moving window. See baseline.smooth_window().

Parameters:
  • eyes (list) – list of eyes to smooth; if empty, all available eyes are smoothed

  • window (str) –

    (the type of window from ‘flat’, ‘hanning’, ‘hamming’, ‘bartlett’, ‘blackman’);

    flat window will produce a moving average smoothing.

  • winsize (float) – the length of the window in ms

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes

summary()[source]

Return a summary of the dataset as a dictionary.

Returns:

dictionary containing description of dataset

Return type:

dict

GazeData

class pypillometry.GazeData(time=None, left_x=None, left_y=None, right_x=None, right_y=None, event_onsets=None, event_labels=None, sampling_rate=None, experimental_setup=None, name=None, calibration=None, fill_time_discontinuities=True, keep_orig=False, info=None, inplace=False)[source]

Class representing Eye-Tracking data (x,y) from one or two eyes.

If you also want to store pupil-size, use the EyeData class. If you only want to store pupil-size, use the PupilData class.

Parameters:
  • time (ndarray) – timing array or None, in which case the time-array goes from [0,maxT] using sampling_rate (in ms)

  • left_x (ndarray) – data from left eye (at least one of the eyes must be provided, both x and y)

  • left_y (ndarray) – data from left eye (at least one of the eyes must be provided, both x and y)

  • right_x (ndarray) – data from right eye (at least one of the eyes must be provided, both x and y)

  • right_y (ndarray) – data from right eye (at least one of the eyes must be provided, both x and y)

  • sampling_rate (float) – sampling-rate of the signal in Hz; if None,

  • experimental_setup (ExperimentalSetup, optional) – Geometric model of the experimental setup including screen geometry, eye position, camera position, and screen orientation.

  • name (str) – name of the dataset or None (in which case a random string is selected)

  • event_onsets (ndarray) – time-onsets of any events in the data (in ms, matched in time vector)

  • event_labels (ndarray) – for each event in event_onsets, provide a label

  • calibration (dict, optional) – Dictionary of SpatialCalibration objects, one per eye (keys: ‘left’, ‘right’)

  • keep_orig (bool) – keep a copy of the original dataset? If True, a copy of the object as initiated in the constructor is stored in member original

  • fill_time_discontinuities (bool) – sometimes, when the eyetracker loses signal, no entry in the EDF is made; when this option is True, such entries will be made and the signal set to 0 there (or do it later using fill_time_discontinuities())

  • inplace (bool) – if True, the object is modified in place; if False, a new object is returned this object-level property can be overwritten by the method-level inplace argument default is “False”

Attributes:
blinks

Return blinks (intervals) for all eyes.

eyes

Return a list of available eyes in the dataset.

plot
variables

Return a list of available variables in the dataset.

Methods

add_to_history(event)

Add event to history

apply_history(obj)

Apply history of operations done on self to obj.

blink_stats([eyes, units])

Return statistics on blink durations.

blinks_merge_close([eyes, variables, ...])

Merge blinks that are close together.

copy([new_name])

Make and return a deep-copy of the pupil data.

downsample(fsd[, dsfac, inplace])

Simple downsampling scheme using mean within the downsampling window.

drop_original([inplace])

Drop original dataset from record (e.g., to save space).

fill_time_discontinuities([yval, print_info])

find gaps in the time-vector and fill them in (add zeros to the signal)

from_eyelink(fname[, return_edf_obj, ...])

Reads a GenericEyedata object from an Eyelink file.

from_file(fname)

Reads a GenericEyedata object from a pickle-file.

get_blinks([eyes, variables, units])

Get blinks as Intervals object or dict of Intervals.

get_duration([units])

Return duration of the dataset in units specified.

get_events([units])

Get events as an Events object.

get_interpolated_blinks([eyes, variables, units])

Get interpolated blinks as Intervals object or dict of Intervals.

get_intervals(event_select[, interval, ...])

Return an Intervals object containing intervals relative to event-onsets.

get_size()

Return the size of the object in bytes.

interpolate_intervals(intervals[, eyes, ...])

Interpolate data within specified intervals.

mask_as_intervals([eyes, variables, units, ...])

Convert masks to Intervals objects.

mask_eye_divergences([threshold, thr_type, ...])

Calculate Euclidean distance between left and right eye coordinates and detect divergences.

mask_intervals(intervals[, eyes, variables, ...])

Apply Intervals as masks to selected data.

mask_offscreen_coords([eyes, apply_mask, ...])

Detect and mask gaze coordinates that fall outside the screen boundaries.

merge_eyes([eyes, variables, method, ...])

Merge data from both eyes into a single variable.

merge_masks([inplace])

Merge masks of all variables into a single joint mask.

nblinks([eyes, variables])

Return number of detected blinks.

nevents()

Return number of events in data.

print_history()

Pretty-print the history of the current dataset (which manipulations where done on it).

reset_time([t0, inplace])

Resets time so that the time-array starts at time zero (t0).

scale([variables, mean, sd, eyes, inplace])

Scale the signal by subtracting mean and dividing by sd.

set_blinks(intervals[, eyes, variables, ...])

Set blinks for specified eyes and variables.

set_event_onsets(event_onsets, event_labels)

Set onsets of events in the data

set_events(events[, inplace])

Replace event onsets and labels from an Events object.

set_experimental_setup(**kwargs)

Set or update the experimental setup geometry.

stat_per_event([intervals, interval, ...])

Return result of applying a statistical function to data in a given interval relative to event-onsets.

sub_slice([start, end, units, inplace])

Return a new EyeData object that is a shortened version of the current one (contains all data between start and end in units given by units (one of "ms", "sec", "min", "h").

summary()

Return a summary of the dataset as a dictionary.

unscale([variables, mean, sd, eyes, inplace])

Scale back to original values using either values provided as arguments or the values stored in scale_params.

write_file(fname)

Save to file (using pickle).

mask_eye_divergences(threshold=0.99, thr_type='percentile', store_as=None, apply_mask=True, ignore_existing_mask=True, inplace=None)[source]

Calculate Euclidean distance between left and right eye coordinates and detect divergences.

This method computes the distance between corresponding (x,y) coordinates in the left and right eyes. Points where the distance exceeds a threshold are detected as divergences. When apply_mask=True, these points are masked. When apply_mask=False, the divergences are returned as Intervals objects.

Parameters:
  • threshold (float, default=.99) – If thr_type is “percentile”: percentile value (0-1) for threshold calculation. If thr_type is “pixel”: maximum allowed distance in pixels.

  • thr_type (str, default="percentile") – Type of threshold to apply: - “percentile”: threshold is calculated as the given percentile of the distance distribution - “pixel”: threshold is the maximum allowed distance in pixels

  • store_as (str or None, default=None) – Variable name to store the distance timeseries. If None, distance is not stored.

  • apply_mask (bool, default=True) – If True, apply detected divergences as masks to the data and return self. If False, return detected divergences as dict of Intervals objects.

  • ignore_existing_mask (bool, default=True) – If True (default), check all data points including those already masked (e.g., from blinks). If False, only check non-masked data points for divergences.

  • inplace (bool or None) – If True, make change in-place and return the object. If False, make and return copy before making changes. If None, use the object-level setting.

Returns:

If apply_mask=True: returns self for chaining. If apply_mask=False: returns Intervals object containing detected divergence intervals.

Return type:

GazeData or Intervals

Raises:

ValueError – If both left and right eye data are not available. If thr_type is not “percentile” or “pixel”.

Examples

>>> # Mask divergences at 99th percentile
>>> gaze_data = gaze_data.mask_eye_divergences(threshold=0.99, thr_type="percentile")
>>> # Detect divergences without masking
>>> divergences = gaze_data.mask_eye_divergences(threshold=0.99, apply_mask=False)
>>> # Mask divergences beyond 100 pixels
>>> gaze_data = gaze_data.mask_eye_divergences(threshold=100, thr_type="pixel")
>>> # Only check non-masked data points
>>> gaze_data = gaze_data.mask_eye_divergences(ignore_existing_mask=False)
mask_offscreen_coords(eyes=[], apply_mask=True, ignore_existing_mask=False, inplace=None)[source]

Detect and mask gaze coordinates that fall outside the screen boundaries.

This method identifies points where the (x,y) coordinates fall outside the defined screen limits. When apply_mask=True, these points are masked. When apply_mask=False, the offscreen periods are returned as Intervals objects.

Parameters:
  • eyes (str or list, default=[]) – Eye(s) to check for offscreen coordinates. If empty, checks all available eyes. Can be a single eye name (e.g., “left”) or a list (e.g., [“left”, “right”]).

  • apply_mask (bool, default=True) – If True, apply detected offscreen periods as masks to the data and return self. If False, return detected offscreen periods as dict of Intervals objects.

  • ignore_existing_mask (bool, default=False) – If False (default), only check non-masked data points for offscreen coordinates. If True, check all data points including those already masked (e.g., from blinks).

  • inplace (bool or None) – If True, make change in-place and return the object. If False, make and return copy before making changes. If None, use the object-level setting.

Returns:

If apply_mask=True: returns self for chaining. If apply_mask=False: returns dict of Intervals objects (one per eye) containing detected offscreen intervals.

Return type:

GazeData or dict of Intervals

Examples

>>> # Mask offscreen coordinates for all eyes
>>> gaze_data = gaze_data.mask_offscreen_coords()
>>> # Detect offscreen periods without masking
>>> offscreen = gaze_data.mask_offscreen_coords(apply_mask=False)
>>> # Mask offscreen coordinates for left eye only
>>> gaze_data = gaze_data.mask_offscreen_coords(eyes='left')
>>> # Check all data including already masked points (e.g., during blinks)
>>> gaze_data = gaze_data.mask_offscreen_coords(ignore_existing_mask=True)
set_experimental_setup(**kwargs)[source]

Set or update the experimental setup geometry.

Creates a new ExperimentalSetup or updates the existing one with the provided parameters. All parameters are passed through to ExperimentalSetup constructor.

Parameters:

**kwargs – Any parameters accepted by ExperimentalSetup: - screen_resolution: tuple (width, height) in pixels - physical_screen_size: tuple (width, height) with units - eye_to_screen_center: distance (d) - screen_offset: tuple (delta_x, delta_y) - offset of screen center from eye - eye_to_screen_center: alternative distance specification - screen_pitch: tilt angle (alpha_tilt) - screen_yaw: tilt angle (beta_tilt) - camera_offset: tuple (x, y, z) in eye-centric frame - camera_spherical: tuple (theta, phi, r) - ipd: inter-pupillary distance

Examples

>>> data.set_experimental_setup(
...     screen_resolution=(1920, 1080),
...     physical_screen_size=("52 cm", "29 cm"),
...     eye_to_screen_center="65 cm",
... )
summary()[source]

Return a summary of the dataset as a dictionary.

Returns:

dictionary containing description of dataset

Return type:

dict

Plotting

class pypillometry.EyePlotter(obj)[source]

Methods

plot_blinks([eyes, variables, pdf_file, ...])

Plot detected blinks in separate subplots.

plot_calibration([eyes, show_surface, ...])

Plot spatial calibration data for one or more eyes in subplots.

plot_experimental_setup([theta, phi, ...])

Plot visualization of eye-tracking experimental setup geometry.

plot_heatmap([plot_range, eyes, ...])

Plot EyeData as a heatmap.

plot_intervals(intervals[, eyes, variables, ...])

plot_masked([eyes, variables, units, merge, ...])

Plot masked intervals for specified eyes and variables.

plot_pupil_foreshortening_error_surface([...])

Plot a heatmap showing average pupil size across x/y gaze positions.

plot_scanpath([plot_range, eyes, ...])

Plot EyeData as a scanpath.

plot_timeseries([plot_range, variables, ...])

Plot a part of the EyeData.

plot_timeseries_segments([pdf_file, interv, ...])

Plot the whole dataset chunked up into segments (usually to a PDF file).

pupil_plot([eyes, plot_range, show_events, ...])

Make a plot of the pupil data using matplotlib.

pupil_plot_segments([pdf_file, interv, ...])

Plot the whole dataset chunked up into segments (usually to a PDF file).

plot_experimental_setup(theta=None, phi=None, calibration=None, show_gaze_samples=True, n_gaze_samples=9, ax=None, viewing_angle=None, projection='2d')[source]

Plot visualization of eye-tracking experimental setup geometry.

Shows the spatial relationship between eye, camera, and screen using the experimental parameters stored in the EyeData object. Delegates to ExperimentalSetup.plot().

Parameters:
  • theta (float, optional) – Camera polar angle in radians. If None, uses setup’s theta or calibration’s theta.

  • phi (float, optional) – Camera azimuthal angle in radians. If None, uses setup’s phi or calibration’s phi.

  • calibration (ForeshorteningCalibration, optional) – Fitted calibration object containing theta and phi.

  • show_gaze_samples (bool, default True) – Show sample gaze vectors to screen positions

  • n_gaze_samples (int, default 9) – Number of sample gaze positions

  • ax (matplotlib axis, optional) – Existing axis to plot on (only for ‘3d’ projection)

  • viewing_angle (tuple, optional) – Viewing angle for 3D projection (elev, azim) or (elev, azim, roll) in degrees.

  • projection (str, default '2d') – ‘2d’ for three orthogonal views, ‘3d’ for interactive 3D view

Return type:

tuple

Returns:

  • fig (matplotlib Figure)

  • ax (matplotlib axis or array of axes)

Examples

>>> # Use camera geometry from setup
>>> data.plot.plot_experimental_setup()
>>>
>>> # Use fitted angles from calibration
>>> calib = data.fit_foreshortening(eye='left')
>>> data.plot.plot_experimental_setup(calibration=calib)
>>>
>>> # Override angles
>>> data.plot.plot_experimental_setup(theta=np.radians(20), phi=np.radians(-90))
plot_pupil_foreshortening_error_surface(eyes=[], plot_range=(-inf, inf), units='sec', show_screen=True, cmap='jet', gridsize=30, vmin=None, vmax=None, min_samples=None, smooth=None, limits=None)[source]

Plot a heatmap showing average pupil size across x/y gaze positions.

This visualizes how pupil size varies across different gaze positions, which can reveal foreshortening effects (pupils appear smaller when looking away from the camera) or other spatial artifacts. Each eye is plotted in a separate subplot.

Parameters:
  • eyes (str or list, optional) – Which eye(s) to plot: “left”, “right”, “average”, or a list of these. Default is [] which plots all available eyes.

  • plot_range (tuple, optional) – The time range to include in the analysis. Default is (-np.inf, +np.inf), i.e. all data.

  • units (str, optional) – Time units for plot_range. Default is “sec”.

  • show_screen (bool, optional) – Whether to plot the screen limits. Default is True.

  • cmap (str, optional) – Colormap to use. Default is “jet”.

  • gridsize (int, optional) – Number of bins in each direction. Default is 30.

  • vmin (float, optional) – Minimum value for color scale. If None, uses data minimum.

  • vmax (float, optional) – Maximum value for color scale. If None, uses data maximum.

  • min_samples (int, optional) – Minimum number of samples required in a bin to display it. Bins with fewer samples will not be shown. If None (default), automatically calculates a threshold at the 10th percentile of bin counts, effectively displaying only the top 90% of bins by sample count.

  • smooth (float, optional) – If provided, applies Gaussian smoothing to the binned surface. The value is the sigma of the Gaussian kernel in bin units (e.g., smooth=1 applies minimal smoothing with a 1-bin sigma, smooth=2 applies more smoothing). When smooth is provided, uses a rectangular grid instead of hexbin.

  • limits (tuple, optional) – Axis limits as (xmin, xmax, ymin, ymax). If not provided, uses screen limits when available (and data falls within), otherwise uses data extent.

Returns:

Creates a matplotlib figure with the heatmap(s)

Return type:

None

Examples

Plot foreshortening effect for left eye:

>>> data.plot.plot_pupil_foreshortening_error_surface('left')

Plot for multiple eyes:

>>> data.plot.plot_pupil_foreshortening_error_surface(['left', 'right'])

Plot all available eyes with custom color range:

>>> data.plot.plot_pupil_foreshortening_error_surface(vmin=3, vmax=5)

Plot with a specific minimum sample threshold:

>>> data.plot.plot_pupil_foreshortening_error_surface(min_samples=50)

Plot with Gaussian smoothing:

>>> data.plot.plot_pupil_foreshortening_error_surface(smooth=1.5)

Plot with custom limits:

>>> data.plot.plot_pupil_foreshortening_error_surface(limits=(0, 1920, 0, 1080))
class pypillometry.PupilPlotter(obj)[source]

Class for plotting pupil data. The class is initialized with a GenericEyeData object and provides methods to plot the data in various ways.

Methods

plot_blinks([eyes, variables, pdf_file, ...])

Plot detected blinks in separate subplots.

plot_intervals(intervals[, eyes, variables, ...])

plot_masked([eyes, variables, units, merge, ...])

Plot masked intervals for specified eyes and variables.

plot_timeseries([plot_range, variables, ...])

Plot a part of the EyeData.

plot_timeseries_segments([pdf_file, interv, ...])

Plot the whole dataset chunked up into segments (usually to a PDF file).

pupil_plot([eyes, plot_range, show_events, ...])

Make a plot of the pupil data using matplotlib.

pupil_plot_segments([pdf_file, interv, ...])

Plot the whole dataset chunked up into segments (usually to a PDF file).

Plot detected blinks in separate subplots.

Parameters:
  • eyes (str or list) – Eyes to plot

  • variables (str or list) – Variables to plot

  • pdf_file (str or None) – Save to PDF file if provided

  • nrow (int) – Number of rows per figure

  • ncol (int) – Number of columns per figure

  • figsize (tuple) – Figure size (width, height)

  • pre_blink (float) – Time before blink to include (in ms)

  • post_blink (float) – Time after blink to include (in ms)

  • units (str) – Display units for time axis

  • show_index (bool) – Show blink index numbers

Returns:

List of matplotlib Figure objects

Return type:

list

pupil_plot(eyes=[], plot_range=(-inf, inf), show_events=True, show_blinks=True, units='sec', label_prefix='', style=None)[source]

Make a plot of the pupil data using matplotlib.

Has pupil-specific options which makes it different from GazePlotter.plot_timeseries().

Parameters:
  • eyes (list) – list of eyes to plot; if empty, all available eyes are plotted

  • plot_range (tuple (start,end)) – plot from start to end (in units of units)

  • units (str) – one of “sec”=seconds, “ms”=millisec, “min”=minutes, “h”=hours

  • show_events (bool) – plot events as vertical lines with labels

  • show_blinks (bool) – highlight detected blinks

  • label_prefix (str) – Prefix to add to labels in the legend. Useful for overlaying multiple datasets. Default is “” (no prefix).

  • style (dict or dict of dicts) – Styling for plotted lines. Can be: - Single dict: Applied to all eyes with automatic differentiation (e.g., {‘color’: ‘red’}) - Dict of dicts: Per-eye styling (e.g., {‘left’: {‘linestyle’: ‘-‘}, ‘right’: {‘linestyle’: ‘–‘}}) Default is None (uses matplotlib defaults with automatic per-eye colors and linestyles).

Return type:

None

pupil_plot_segments(pdf_file=None, interv=1, figsize=(15, 5), ylim=None, units='min', **kwargs)[source]

Plot the whole dataset chunked up into segments (usually to a PDF file).

Parameters:
  • pdf_file (str or None) – file name to store the PDF; if None, no PDF is written

  • interv (float) – duration of each of the segments to be plotted (in units specified by units)

  • figsize (Tuple[int,int]) – dimensions of the figures

  • units (str, optional) – Time units for segment boundaries passed to PupilData.pupil_plot(). Default “min”.

  • kwargs – arguments passed to PupilData.pupil_plot()

Returns:

  • figs (list of matplotlib.Figure objects)

class pypillometry.GazePlotter(obj)[source]

Class for plotting eye data. The class is initialized with an EyeData object and provides methods to plot the data in various ways.

Methods

plot_calibration([eyes, show_surface, ...])

Plot spatial calibration data for one or more eyes in subplots.

plot_heatmap([plot_range, eyes, ...])

Plot EyeData as a heatmap.

plot_intervals(intervals[, eyes, variables, ...])

plot_masked([eyes, variables, units, merge, ...])

Plot masked intervals for specified eyes and variables.

plot_scanpath([plot_range, eyes, ...])

Plot EyeData as a scanpath.

plot_timeseries([plot_range, variables, ...])

Plot a part of the EyeData.

plot_timeseries_segments([pdf_file, interv, ...])

Plot the whole dataset chunked up into segments (usually to a PDF file).

plot_calibration(eyes=None, show_surface=True, interpolation='rbf', figsize=(10, 8))[source]

Plot spatial calibration data for one or more eyes in subplots.

Creates a figure with subplots for each eye and calls the plot() method on each SpatialCalibration object to show calibration accuracy with target points (black X), measured points (dark blue +), and optional interpolated error surface.

Parameters:
  • eyes (str, list, or None, default None) – Which eye(s) to plot. If None or empty list, plots all available eyes. Can be a single eye name (e.g., ‘left’) or list of eye names (e.g., [‘left’, ‘right’]).

  • show_surface (bool, default True) – If True, show interpolated error surface as background. If False, show only the calibration points.

  • interpolation (str, default 'rbf') – Interpolation method for surface (only used if show_surface=True). Options: ‘rbf’, ‘linear’, ‘cubic’, ‘nearest’

  • figsize (tuple, default (10, 8)) – Figure size per subplot (width, height) in inches.

Returns:

  • fig (matplotlib.figure.Figure) – The figure object

  • axes (list or matplotlib.axes.Axes) – List of axis objects (or single axis if only one eye)

Raises:

ValueError – If no calibration data is available

Examples

>>> import pypillometry as pp
>>> data = pp.EyeData.from_eyelink('data.edf')
>>> # Plot all eyes with surface
>>> fig, axes = data.plot.plot_calibration()
>>>
>>> # Plot only left eye without surface
>>> fig, ax = data.plot.plot_calibration(eyes='left', show_surface=False)
>>>
>>> # Plot specific eyes
>>> fig, axes = data.plot.plot_calibration(eyes=['left', 'right'])
plot_heatmap(plot_range=(-inf, inf), eyes=[], show_screen=True, show_masked=False, rois=None, roi_style={}, units='sec', cmap='jet', gridsize=30, min_samples=1, smooth=None, limits=None)[source]

Plot EyeData as a heatmap. Typically used for a large amount of data to spot the most frequent locations. To plot a scanpath, use plot_scanpath() instead. Each eye is plotted in a separate subplot.

Return type:

None

plot_scanpath(plot_range=(-inf, inf), eyes=[], show_screen=True, rois=None, roi_style={}, show_onsets=True, title='', units=None, figsize=(10, 10))[source]

Plot EyeData as a scanpath. Typically used for single trials or another small amount of data. To plot a larger amount of data, use plot_heatmap() instead.

If several eyes are available, they are plotted in the same figure in different colors. You can choose between them using the plot_eyes parameter.

Return type:

None

Supporting classes

These classes are used internally by the main classes will only rarely be used directly by the user.

GenericEyeData

class pypillometry.GenericEyeData[source]

Generic class for eyedata. Defines the basic structure of an eyedata object and implements some basic functions.

Attributes:
blinks

Return blinks (intervals) for all eyes.

eyes

Return a list of available eyes in the dataset.

variables

Return a list of available variables in the dataset.

Methods

add_to_history(event)

Add event to history

apply_history(obj)

Apply history of operations done on self to obj.

blink_stats([eyes, units])

Return statistics on blink durations.

blinks_merge_close([eyes, variables, ...])

Merge blinks that are close together.

copy([new_name])

Make and return a deep-copy of the pupil data.

downsample(fsd[, dsfac, inplace])

Simple downsampling scheme using mean within the downsampling window.

drop_original([inplace])

Drop original dataset from record (e.g., to save space).

fill_time_discontinuities([yval, print_info])

find gaps in the time-vector and fill them in (add zeros to the signal)

from_eyelink(fname[, return_edf_obj, ...])

Reads a GenericEyedata object from an Eyelink file.

from_file(fname)

Reads a GenericEyedata object from a pickle-file.

get_blinks([eyes, variables, units])

Get blinks as Intervals object or dict of Intervals.

get_duration([units])

Return duration of the dataset in units specified.

get_events([units])

Get events as an Events object.

get_interpolated_blinks([eyes, variables, units])

Get interpolated blinks as Intervals object or dict of Intervals.

get_intervals(event_select[, interval, ...])

Return an Intervals object containing intervals relative to event-onsets.

get_size()

Return the size of the object in bytes.

interpolate_intervals(intervals[, eyes, ...])

Interpolate data within specified intervals.

mask_as_intervals([eyes, variables, units, ...])

Convert masks to Intervals objects.

mask_intervals(intervals[, eyes, variables, ...])

Apply Intervals as masks to selected data.

merge_eyes([eyes, variables, method, ...])

Merge data from both eyes into a single variable.

merge_masks([inplace])

Merge masks of all variables into a single joint mask.

nblinks([eyes, variables])

Return number of detected blinks.

nevents()

Return number of events in data.

print_history()

Pretty-print the history of the current dataset (which manipulations where done on it).

reset_time([t0, inplace])

Resets time so that the time-array starts at time zero (t0).

scale([variables, mean, sd, eyes, inplace])

Scale the signal by subtracting mean and dividing by sd.

set_blinks(intervals[, eyes, variables, ...])

Set blinks for specified eyes and variables.

set_event_onsets(event_onsets, event_labels)

Set onsets of events in the data

set_events(events[, inplace])

Replace event onsets and labels from an Events object.

stat_per_event([intervals, interval, ...])

Return result of applying a statistical function to data in a given interval relative to event-onsets.

sub_slice([start, end, units, inplace])

Return a new EyeData object that is a shortened version of the current one (contains all data between start and end in units given by units (one of "ms", "sec", "min", "h").

summary()

Return a summary of the GenericEyedata-object.

unscale([variables, mean, sd, eyes, inplace])

Scale back to original values using either values provided as arguments or the values stored in scale_params.

write_file(fname)

Save to file (using pickle).

add_to_history(event)[source]

Add event to history

apply_history(obj)[source]

Apply history of operations done on self to obj.

Parameters:

obj (GenericEyedata) – object of class GenericEyedata to which the operations are to be transferred

Return type:

copy of the GenericEyedata-object to which the operations in self were applied

Return statistics on blink durations.

Parameters:
  • eyes (list) – Eyes to process. If empty, all eyes are processed.

  • units (str) – Units for statistics: “ms”, “sec”, “min”, or “h”

Returns:

Dictionary mapping eye name to stats dict (or None if no blinks)

Return type:

dict

Return blinks (intervals) for all eyes.

Returns:

dictionary with blinks for each eye

Return type:

dict

Merge blinks that are close together.

Parameters:
  • eyes (list) – Eyes to process. If empty, all eyes are processed.

  • variables (list) – Variables to process. If empty, all variables are processed.

  • distance (float) – Merge blinks closer than this distance (in units specified by units)

  • units (str) – Units for distance. Can be “ms”, “sec”, “min”, or “h”. Default “ms”.

  • apply_mask (bool, default=True) – If True, apply merged blinks as masks to the data and return self. If False, return merged blinks as dict of Intervals objects without applying masks.

  • inplace (bool or None) – If True, modify in place. If False, return copy. Only relevant when apply_mask=True.

Returns:

If apply_mask=True: returns modified object for chaining. If apply_mask=False: returns dict of Intervals objects (one per eye/variable combination).

Return type:

GenericEyeData or dict of Intervals

copy(new_name=None)[source]

Make and return a deep-copy of the pupil data.

Parameters:

new_name (str, optional) – New name for the copy. If None, “_copy” is appended to the original name.

downsample(fsd, dsfac=False, inplace=None)[source]

Simple downsampling scheme using mean within the downsampling window.

All data fields are downsampled simultaneously. See baseline.downsample().

Parameters:
  • fsd (float) – new sampling-rate or decimate-factor

  • dsfac (bool) – if False, fsd is the new sampling rate; if True, fsd is the decimate factor

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes

drop_original(inplace=None)[source]

Drop original dataset from record (e.g., to save space).

Parameters:

inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes if None, use the setting of the object (specified in constructor)

property eyes: List[str]

Return a list of available eyes in the dataset.

fill_time_discontinuities(yval=0, print_info=True)[source]

find gaps in the time-vector and fill them in (add zeros to the signal)

Reads a GenericEyedata object from an Eyelink file.

All “messages” are stored as event_labels (can be filtered later) and it tries to be smart to detect different information from the EDF file. Spatial calibration/validation data is automatically parsed and stored in the calibration attribute as SpatialCalibration objects.

However, the EDF file may contain other information of interest, e.g., eyelink-detected saccades, etc. If you need more control, use the “eyelinkio” package directly and create the object manually.

Parameters:
  • fname (str) – filename of the EDF file

  • return_edf_obj (bool) – if True, return a tuple with the object of class GenericEyedata and the object returned by the “eyelinkio” package if False, return only the object of class GenericEyedata

  • remove_eyelink_triggers (bool) – if True, remove all Eyelink triggers from the event_labels (related to eye-tracker settings, calibration, validation etc)

  • kwargs (dict) – additional arguments to pass to the pypillometry.io.read_eyelink()

Returns:

object of class GenericEyedata or tuple with the object of class GenericEyedata and the object returned by the “eyelinkio” package

Return type:

GenericEyedata or tuple

Examples

>>> import pypillometry as pp
>>> d = pp.EyeData.from_eyelink('data.edf')
>>> # Access calibration data
>>> print(d.calibration['left'])
<SpatialCalibration: left eye, HV9, n=9, error=0.45±0.23° (max=0.79°)>
classmethod from_file(fname)[source]

Reads a GenericEyedata object from a pickle-file. Use as pypillometry.PupilData.from_file("yourfile.pd").

Parameters:

fname (str) – filename

Get blinks as Intervals object or dict of Intervals.

Parameters:
  • eyes (str or list) – Eye(s) to get blinks for. If multiple, returns dict.

  • variables (str or list) – Variable(s) to get blinks for. If multiple, returns dict.

  • units (str or None, optional) – Units for intervals: “ms”, “sec”, “min”, “h”, or None for indices

Returns:

If single eye and variable: returns Intervals object. If multiple eyes/variables: returns dict with keys like “left_pupil”.

Return type:

Intervals or dict

Examples

>>> blinks = data.get_blinks('left', 'pupil')
>>> blinks_ms = data.get_blinks('left', 'pupil', units="ms")
>>> blinks_dict = data.get_blinks(['left', 'right'], 'pupil')
>>> blinks_idx = blinks_ms.to_units("indices")
get_duration(units='min')[source]

Return duration of the dataset in units specified.

Parameters:

units (str, optional) – unit one of “min”, “sec”, “h”, by default “min”

Returns:

duration of dataset in specified units

Return type:

float

get_events(units='ms')[source]

Get events as an Events object.

Returns the event onsets and labels stored in the dataset as an Events object, which provides convenient filtering and display capabilities.

Parameters:

units (str, optional) – Units for the event onsets: “ms”, “sec”, “min”, or “h”. Default is “ms” (the internal storage format).

Returns:

Events object containing the event onsets and labels

Return type:

Events

Examples

>>> events = data.get_events()
>>> len(events)
42
>>> # Get events in seconds
>>> events_sec = data.get_events(units="sec")
>>> # Filter and work with events
>>> stim_events = data.get_events().filter("stim")

See also

set_events

Replace events from an Events object

get_intervals

Extract intervals around events

Get interpolated blinks as Intervals object or dict of Intervals.

Interpolated blinks are the blink regions that were successfully interpolated by pupil_blinks_interpolate(). These may differ from detected blinks because: - Blink boundaries are refined using velocity thresholds - Some blinks may be skipped if they’re too short to interpolate

Parameters:
  • eyes (str or list) – Eye(s) to get interpolated blinks for. If multiple, returns dict.

  • variables (str or list) – Variable(s) to get interpolated blinks for. If multiple, returns dict.

  • units (str or None, optional) – Units for intervals: “ms”, “sec”, “min”, “h”, or None for indices

Returns:

If single eye and variable: returns Intervals object. If multiple eyes/variables: returns dict with keys like “left_pupil”.

Return type:

Intervals or dict

See also

get_blinks

Get detected (not interpolated) blinks

pupil_blinks_interpolate

Interpolate blinks

get_intervals(event_select, interval=(-200, 200), units=None, label=None, **kwargs)[source]

Return an Intervals object containing intervals relative to event-onsets. For example, extract the interval before and after a stimulus has been presented. It is possible to select based on the event label, e.g. only select events matching “stimulus” or “response”. It is also possible to select the intervals situated between two different events, e.g., trial start and response by specifying event_select as a tuple with two entriess.

Parameters:
  • event_select (str, tuple, function, or Events) –

    variable describing which events to select and align to - if str: use all events whose label contains the string - if function: apply function to all labels, use those where the function returns True - if tuple: use all events between the two events specified in the tuple.

    Both selectors must result in identical number of events.

    • if Events: use the events from the Events object directly

  • interval (tuple (min,max)) – time-window relative to event-onset (0 is event-onset); i.e., negative numbers are before the event, positive numbers after. Units are defined by the units parameter

  • units (str or None) – units of the interval (one of “ms”, “sec”, “min”, “h”); units=None means that the interval in sampling units (i.e., indices into the time-array)

  • label (str or None) – optional label for the Intervals object. If None, a label is automatically generated from the event_select parameter

  • kwargs (dict) – passed onto the event_select function

Returns:

  • result (Intervals) – Intervals object containing interval on- and offsets for each match, with associated metadata (event labels, indices, units)

get_size()[source]

Return the size of the object in bytes.

Returns:

Total size of the object, including data and all attributes.

Return type:

ByteSize

interpolate_intervals(intervals, eyes=[], variables=[], method='linear', store_as_suffix=None, inplace=None)[source]

Interpolate data within specified intervals.

This function replaces data within the specified intervals with interpolated values based on the boundary points just outside each interval.

Parameters:
  • intervals (Intervals or dict) –

    Either: - A single Intervals object: applied to all specified eyes/variables - A dict of Intervals: keys like “left_pupil”, “right_x”, etc.

    When dict is provided, eyes and variables are ignored.

  • eyes (str or list, optional) – Eye(s) to interpolate. If empty, applies to all available eyes. Ignored if intervals is a dict.

  • variables (str or list, optional) – Variable(s) to interpolate. If empty, applies to all available variables. Ignored if intervals is a dict.

  • method (str, default "linear") – Interpolation method. Options: “linear”, “nearest”, “zero”, “slinear”, “quadratic”, “cubic”, “previous”, “next”. Passed to scipy.interpolate.interp1d.

  • store_as_suffix (str or None, default None) – If None, replace the original data. If a string, store interpolated data in a new variable with this suffix (e.g., “_interp” creates “left_pupil_interp”).

  • inplace (bool, optional) – If True, modify in-place. If False, return a copy. If None, use object’s default setting.

Returns:

The object with interpolated data.

Return type:

GenericEyeData

Examples

Interpolate blinks for left eye pupil data:

>>> blinks = data.get_blinks(eyes='left', variables='pupil')
>>> data.interpolate_intervals(blinks, eyes=['left'], variables=['pupil'])

Interpolate using a dict of intervals:

>>> blinks = data.get_blinks()  # returns dict
>>> data.interpolate_intervals(blinks)

Store interpolated data in a new variable:

>>> data.interpolate_intervals(blinks, store_as_suffix="_interp")
>>> # Access via data['left', 'pupil_interp']

Use cubic interpolation:

>>> data.interpolate_intervals(blinks, method="cubic")

See also

mask_intervals

Apply intervals as masks without interpolation

get_blinks

Retrieve stored blink intervals

mask_as_intervals(eyes=[], variables=[], units=None, label=None)[source]

Convert masks to Intervals objects.

Parameters:
  • eyes (str or list) – Eye(s) to get masks for. If multiple, returns dict.

  • variables (str or list) – Variable(s) to get masks for. If multiple, returns dict.

  • units (str or None, optional) – Units for intervals: “ms”, “sec”, “min”, “h”, or None for indices. Default is None (indices).

  • label (str, optional) – Descriptive label for the intervals. Default is None.

Returns:

If single eye and variable: returns Intervals object. If multiple eyes/variables: returns dict with keys like “left_pupil”.

Return type:

Intervals or dict

Examples

>>> mask_intervals = data.mask_as_intervals('left', 'pupil')
>>> mask_ms = data.mask_as_intervals('left', 'pupil', units='ms')
>>> mask_dict = data.mask_as_intervals(['left', 'right'], 'pupil')
mask_intervals(intervals, eyes=[], variables=[], inplace=None)[source]

Apply Intervals as masks to selected data.

Takes detected intervals (e.g., blinks, artifacts) and applies them as masks to specified eyes and variables.

Parameters:
  • intervals (Intervals or dict) –

    Either: - A single Intervals object: applied to all specified eyes/variables - A dict of Intervals: keys like “left_pupil”, “right_x”, etc.

    When dict is provided, eyes and variables are ignored.

  • eyes (list of str, optional) – List of eyes to apply mask to (e.g., [‘left’, ‘right’]). If empty, applies to all available eyes. Ignored if intervals is a dict.

  • variables (list of str, optional) – List of variables to apply mask to (e.g., [‘pupil’, ‘x’, ‘y’]). If empty, applies to all available variables. Ignored if intervals is a dict.

  • inplace (bool, optional) – If True, make change in-place and return the object. If False, make and return copy before making changes. If None, use the object’s default setting.

Returns:

The object with masks applied.

Return type:

GenericEyeData

Examples

Apply blinks from a single Intervals object to left eye pupil data:

>>> blinks = data.pupil_blinks_detect(apply_mask=False)
>>> data.mask_intervals(blinks['left_pupil'], eyes=['left'], variables=['pupil'])

Apply a dict of intervals (one per eye/variable):

>>> blinks = data.pupil_blinks_detect(apply_mask=False)
>>> data.mask_intervals(blinks)  # eyes and variables ignored

Chain with other operations:

>>> data.mask_intervals(blinks).pupil_lowpass_filter()

See also

pupil_blinks_detect

Detect blinks with optional masking

get_blinks

Retrieve stored blink intervals

merge_eyes(eyes=[], variables=[], method='mean', keep_eyes=True, inplace=None)[source]

Merge data from both eyes into a single variable.

Parameters:
  • eyes (list, optional) – list of eyes to merge, by default [] meaning all eyes

  • variables (list, optional) – list of variables to merge, by default [] meaning all variables

  • method (str, optional) – which method to use for merging (one of “mean”, “regress”), by default “mean”

  • keep_eyes (bool, optional) – keep original eye data or drop?, by default True

  • inplace (make change inplace, optional) – if None, use default value in class, by default None

merge_masks(inplace=None)[source]

Merge masks of all variables into a single joint mask.

This function creates a joint mask by taking the logical OR of all individual masks using get_mask(), then applies this joint mask to all variables.

Parameters:

inplace (bool, optional) – If True, make change in-place and return the object. If False, make and return copy before making changes. If None, use the object’s default setting.

Returns:

The object with merged masks.

Return type:

GenericEyeData

Return number of detected blinks. Should be run after detect_blinks().

By default, all eyes and variables are considered.

Parameters:

eyes (list) – list of eyes to consider; if empty, all eyes are considered

Returns:

number of detected blinks

Return type:

int

nevents()[source]

Return number of events in data.

Return type:

int

params: dict

Constructor

print_history()[source]

Pretty-print the history of the current dataset (which manipulations where done on it).

reset_time(t0=None, inplace=None)[source]

Resets time so that the time-array starts at time zero (t0). Resets onsets etc.

Parameters:
  • t0 (float or None) – time at which the PupilData’s time-vector starts; if None, use the first time point

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes if None, use the setting of the object (specified in constructor)

scale(variables=[], mean=None, sd=None, eyes=[], inplace=None)[source]

Scale the signal by subtracting mean and dividing by sd. If these variables are not provided, use the signal’s mean and std. Specify whether to scale x, y, pupil or other variables.

Parameters:
  • variables (str or list) – variables to scale; can be “pupil”, “x”,”y”, “baseline”, “response” or any other variable that is available in the dataset; either a string or a list of strings; available variables can be checked with obj.variables; empty list means all variables

  • mean (None, float or dict) – mean to subtract from signal; if None, use the signal’s mean if dict, provide mean for each eye and variable configuration

  • sd (None, float or dict) – sd to scale with; if None, use the signal’s std if dict, provide sd for each eye and variable configuration

  • eyes (str or list) – list of eyes to consider; if empty, all available eyes are considered

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes if None, use the object’s default setting

Note

Scaling-parameters are being saved in the params[“scale”] argument.

Set blinks for specified eyes and variables.

Parameters:
  • intervals (Intervals or dict) –

    Either: - A single Intervals object: stored for all specified eyes/variables - A dict of Intervals: keys like “left_pupil”, “right_x”, etc.

    When dict is provided, eyes and variables are ignored.

  • eyes (list of str, optional) – List of eyes to set blinks for (e.g., [‘left’, ‘right’]). If empty, applies to all available eyes. Ignored if intervals is a dict.

  • variables (list of str, optional) – List of variables to set blinks for (e.g., [‘pupil’, ‘x’, ‘y’]). If empty, applies to all available variables. Ignored if intervals is a dict.

  • apply_mask (bool, optional) – If True, apply intervals as mask to data. If False, only store intervals. Default is True.

set_event_onsets(event_onsets, event_labels)[source]

Set onsets of events in the data

Parameters:
  • onsets (np.ndarray) – array of onsets (in ms)

  • labels (np.ndarray) – array of labels (strings)

set_events(events, inplace=None)[source]

Replace event onsets and labels from an Events object.

This method updates the internal event_onsets and event_labels arrays from an Events object. The Events object’s onsets are automatically converted to milliseconds (the internal storage format) if needed.

Parameters:
  • events (Events) – Events object containing the new events to set

  • inplace (bool, optional) – if True, make change in-place and return the object if False, make and return copy before making changes if None, use the setting of the object (specified in constructor)

Returns:

The object with updated events (may be self or a copy depending on inplace)

Return type:

GenericEyeData

Examples

>>> # Filter events and set them back
>>> events = data.get_events()
>>> stim_events = events.filter("stim")
>>> data.set_events(stim_events)
>>> # Modify events and update
>>> events = data.get_events()
>>> # ... filter or modify events ...
>>> data.set_events(events)

See also

get_events

Get events as an Events object

set_event_onsets

Lower-level method to set events from arrays

stat_per_event(intervals=None, interval=None, event_select=None, eyes=[], variables=[], statfct=<function mean>, units='ms', **kwargs)[source]

Return result of applying a statistical function to data in a given interval relative to event-onsets. For example, extract mean pupil-size in interval before trial onset.

Parameters:
  • intervals (Intervals, optional) – Intervals object to use. If provided, interval and event_select are ignored.

  • interval (tuple (min,max), optional) – time-window in ms relative to event-onset (0 is event-onset). Required if intervals is not provided.

  • event_select (str or function, optional) – variable describing which events to select and align to see GenericEyeData.get_intervals() for details. Required if intervals is not provided.

  • eyes (str or list) – list of eyes to consider; if empty, consider all

  • variables (str or list) – list of variables to consider; if empty, consider all

  • statfct (function) – function mapping np.array to a single number

  • units (str) – units for interval parameter (if used)

  • kwargs (dict) – passed onto the event_select function

Returns:

  • result (np.array or dict) – number of event-onsets long result array; in case of multiple eyes/variables, a dict is returned

sub_slice(start=-inf, end=inf, units=None, inplace=None)[source]

Return a new EyeData object that is a shortened version of the current one (contains all data between start and end in units given by units (one of “ms”, “sec”, “min”, “h”). If units is None, use the units in the time vector.

Parameters:
  • start (float) – start for new dataset

  • end (float) – end of new dataset

  • units (str) – time units in which start and end are provided. (one of “ms”, “sec”, “min”, “h”). If units is None, use the units in the time vector.

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes if None, use the setting of the object (specified in constructor)

abstractmethod summary()[source]

Return a summary of the GenericEyedata-object.

Return type:

dict

unscale(variables=[], mean=None, sd=None, eyes=[], inplace=None)[source]

Scale back to original values using either values provided as arguments or the values stored in scale_params.

Parameters:
  • variables (str or list) – variables to scale; can be “pupil”, “x”,”y”, “baseline”, “response” or any other variable that is available in the dataset; either a string or a list of strings; available variables can be checked with obj.variables

  • eyes (str or list) – list of eyes to consider; if empty, all available eyes are considered

  • mean (None, float or dict) – mean to subtract from signal; if None, use the signal’s mean if dict, provide mean for each eye and variable configuration

  • sd (None, float or Parameters) – sd to scale with; if None, use the signal’s std if dict, provide sd for each eye and variable configuration

  • inplace (bool) – if True, make change in-place and return the object if False, make and return copy before making changes if None, use the object’s default setting

property variables: List[str]

Return a list of available variables in the dataset.

write_file(fname)[source]

Save to file (using pickle).

Parameters:

fname (str) – filename

EyeDataDict

class pypillometry.EyeDataDict(*args, **kwargs)[source]

A dictionary that contains 1-dimensional ndarrays of equal length and with the same datatype (float). Drops empty entries (None or length-0 ndarrays).

Keys stored in this dictionary have the following shape: (eye)_(variable) where eye can be any string identifier (e.g., “left”, “right”, “mean”, “median”, “regress”, or any other custom identifier) and variable is any string identifier (e.g., “x”, “y”, “pupil”, “baseline”, “response”, or any other custom identifier).

The dictionary can be indexed by a string “eye_variable” or by a tuple (“eye”, “variable”) like data[“left”,”x”] or data[“left_x”].

Attributes:
eyes

List of all available eyes.

variables

List of all available variables.

Methods

clear()

copy()

Create a deep copy of the dictionary.

count_masked([per_key])

Count the number of missing values based on masks.

get(k[,d])

get_available_eyes([variable])

Return a list of available eyes.

get_available_variables()

Return a list of available variables.

get_eye(eye)

Return a subset EyeDataDict with all variables for a given eye.

get_mask([key])

Get mask for a specific key or joint mask across all keys.

get_size()

Return the size of the dictionary in bytes.

get_variable(variable)

Return a subset EyeDataDict with all eyes for a given variable.

items()

keys()

pop(k[,d])

If key is not found, d is returned if given, otherwise KeyError is raised.

popitem()

as a 2-tuple; but raise KeyError if D is empty.

set_mask(key, mask)

Set mask for a specific key.

set_with_mask(key, value[, mask, preserve_mask])

Set data array with explicit mask control.

setdefault(k[,d])

update([E, ]**F)

If E present and has a .keys() method, does: for k in E.keys(): D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v

values()

copy()[source]

Create a deep copy of the dictionary.

Return type:

EyeDataDict

count_masked(per_key=False)[source]

Count the number of missing values based on masks.

Parameters:

per_key (bool, optional) – If True, return a dictionary with counts per key. If False, return maximum count across all keys. Default is False.

Returns:

If per_key is False, returns maximum number of missing values across all keys. If per_key is True, returns a dictionary mapping keys to their missing value counts.

Return type:

Union[int, Dict[str, int]]

Examples

>>> d = EyeDataDict(left_x=[1,2,3], left_y=[4,5,6])
>>> d.set_mask("left_x", [0,1,0])  # second value is missing
>>> d.set_mask("left_y", [1,0,1])  # first and last values are missing
>>> d.count_masked()  # max missing values
2
>>> d.count_masked(per_key=True)  # missing values per key
{'left_x': 1, 'left_y': 2}
property eyes: List[str]

List of all available eyes.

get_available_eyes(variable=None)[source]

Return a list of available eyes.

Parameters:

variable (str, optional) – If specified, return only eyes for this variable.

get_available_variables()[source]

Return a list of available variables.

get_eye(eye)[source]

Return a subset EyeDataDict with all variables for a given eye.

Parameters:

eye (str) – The eye to get data for (‘left’, ‘right’, ‘mean’, etc.)

Returns:

A new EyeDataDict containing only data for the specified eye

Return type:

EyeDataDict

Examples

>>> d = EyeDataDict(left_x=[1,2], left_y=[3,4], right_x=[5,6])
>>> left_data = d.get_eye('left')
>>> print(left_data.data.keys())
dict_keys(['left_x', 'left_y'])
get_mask(key=None)[source]

Get mask for a specific key or joint mask across all keys.

Parameters:

key (str, optional) – Key to get mask for. If None, returns logical OR of all masks.

Returns:

Mask array for specified key, or joint mask if no key given.

Return type:

NDArray

get_size()[source]

Return the size of the dictionary in bytes.

Returns:

Total size in bytes.

Return type:

ByteSize

get_variable(variable)[source]

Return a subset EyeDataDict with all eyes for a given variable.

set_mask(key, mask)[source]

Set mask for a specific key.

Return type:

None

set_with_mask(key, value, mask=None, preserve_mask=False)[source]

Set data array with explicit mask control.

This method provides more control over mask handling than __setitem__, which always resets the mask to zeros (except for NaN values).

Parameters:
  • key (str or tuple) – Dictionary key for the data (e.g., “left_pupil” or (“left”, “pupil”))

  • value (NDArray) – Data array to store

  • mask (NDArray, optional) – Mask array to use. If None and preserve_mask=True, keeps existing mask. If None and preserve_mask=False, creates new zero mask (with NaNs masked).

  • preserve_mask (bool, default False) – If True and mask is None, preserve the existing mask for this key. Ignored if mask is explicitly provided.

Return type:

None

Examples

>>> # Set data and preserve existing mask
>>> data_dict.set_with_mask("left_pupil", new_values, preserve_mask=True)
>>> # Set data with explicit mask
>>> data_dict.set_with_mask("left_pupil", new_values, mask=new_mask)
>>> # Set data with fresh zero mask (same as __setitem__)
>>> data_dict.set_with_mask("left_pupil", new_values)
property variables: List[str]

List of all available variables.

Stateless signal-processing functions

These functions are used by the main classes to process the data. They are stateless, meaning that they do not store any state between calls.

baseline.py

Functions for estimating tonic pupillary fluctuations (baseline).

pypillometry.signal.baseline.baseline_envelope(tx, sy, event_onsets, fs=1000, lp=2, prominence_thr=80, interp_method='cubic')[source]

Extract baseline based on the lower envelope of the (filtered) signal.

Steps:

  • filter away noise

  • detect high-prominence throughs in the signal

  • calculate lower envelope based on these peaks

Parameters:
  • tx (np.ndarray) – time-vector in seconds

  • sy (np.ndarray) – raw pupil signal

  • event_onsets (list) – onsets of events (stimuli/responses) in seconds

  • fs (float) – sampling rate in Hz

  • lp (float) – low-pass filter cutoff for removing random noise

  • prominence_thr (float in [0,100]) – percentile of the prominence distribution (of the peaks) to use for determining prominent peaks (see scipy.stats.peak_prominences())

  • interp_method (string, one of ["linear", "cubic", "spline"]) –

    “linear” - linear interpolation between the high-prominence peaks “cubic” - cubic interpolation through all high-prominence peaks “spline” - a smoothing spline that is guaranteed to go through all

    high-prominence peaks and smoothes through all the other (lower-prominence) peaks

Returns:

  • base (np.array) – baseline estimate

pypillometry.signal.baseline.baseline_envelope_iter_bspline(tx, sy, event_onsets, fs, fsd=10, lp=2, lam_sig=1, lam_min=1, lam_max=100, verbose=0)[source]

Extract baseline based (re-)estimating the lower envelope using B-splines. See notebook baseline_interp.ipynb for details. The signal is downsampled (to fsd Hz) for speed.

Parameters:
  • tx (np.ndarray) – time-vector in seconds

  • sy (np.ndarray) – raw pupil signal

  • event_onsets (list) – onsets of events (stimuli/responses) in milliseconds

  • fs (float) – sampling rate in Hz

  • fsd (float) – downsampled sampling rate (if too slow, decrease)

  • lp (float) – lowpass-filter cutoff (Hz)

  • lam_sig (float) – parameter steering how much the baseline is shaped by the non-peaks of the signal

  • lam_min (float) – parameters mapping how much low- and high-prominence peaks influence the baseline

  • lam_max (float) – parameters mapping how much low- and high-prominence peaks influence the baseline

  • verbose (int [0, 100]) – how much information to print (0 nothing, 100 everything)

Returns:

  • (txd,syd,base2,base1) (tuple) – txd: downsampled time-array syd: downsampled and lowpass-filtered pupil signal base1: is the estimated base after the first round base2: is the final baseline estimate

pypillometry.signal.baseline.baseline_pupil_model(tx, sy, event_onsets, fs=1000, lp1=2, lp2=0.2)[source]

Extract baseline based on filtering after removing stim-locked activity.

Steps:

  • filter away noise

  • regress out event-locked activity from the filtered signal using NNLS

  • remove modeled signal from filtered data

  • run another lowpass-filter to get rid of spurious signals

Parameters:
  • tx (np.ndarray) – time-vector in seconds

  • sy (np.ndarray) – raw pupil signal

  • event_onsets (list) – onsets of events (stimuli/responses) in seconds

  • fs (float) – sampling rate in Hz

  • lp1 (float) – low-pass filter cutoff for removing random noise

  • lp2 (float) – low-pass filter cutoff for removing spurious peaks from the baseline-signal

Returns:

  • base (np.array) – baseline estimate

pypillometry.signal.baseline.bspline(txd, knots, spline_degree=3)[source]

Re-implementation from https://mc-stan.org/users/documentation/case-studies/splines_in_stan.html. Similar behaviour as R’s bs() function from the splines-library.

Parameters:
  • txd (np.array) – time-vector

  • knots (np.array) – location of the knots

  • spline_degree (int) – degree of the spline

Returns:

  • B (np.array) – matrix of basis functions

pypillometry.signal.baseline.butter_lowpass(cutoff, fs, order=5)[source]

Get lowpass-filter coefficients for Butterworth-filter.

Parameters:
  • cutoff (float) – lowpass-filter cutoff

  • fs (float) – sampling rate

  • order (int) – filter order

Returns:

  • (b,a) (tuple (float,float)) – filter coefficients

pypillometry.signal.baseline.butter_lowpass_filter(data, cutoff, fs, order=5)[source]

Lowpass-filter signal using a Butterworth-filter.

Parameters:
  • data (np.array) – data to lowpass-filter

  • cutoff (float) – lowpass-filter cutoff

  • fs (float) – sampling rate

  • order (int) – filter order

Returns:

  • y (np.array) – filtered data

pypillometry.signal.baseline.downsample(y, R)[source]

Simple downsampling scheme using mean within the downsampling window.

Parameters:
  • y (np.array) – signal to downsample

  • R (int) – decimate-factor

Returns:

  • y (np.array) – downsampled data

Logging

By default, the log-level is set to INFO which results in a moderate amount of logging information. The logging can be turned off by running logging_disable() and turned back on by running logging_enable(). You can also set the log-level to DEBUG or WARN by running logging_set_level().

pypillometry.logging_set_level(level='INFO')[source]

Set the logging level for all pypillometry submodules.

In the case of DEBUG, the logging for cmdstanpy is also enabled.

Parameters:

level (str) – The logging level. Can be one of “DEBUG”, “INFO”, “WARNING”, “ERROR”, “CRITICAL”.

pypillometry.logging_disable()[source]

Disable logging for all pypillometry submodules.

pypillometry.logging_enable()[source]

Enable logging for all pypillometry submodules.

Modules

io.py

Read/Write data from/to disk.

pypillometry.io.load_study_local(path, config_file='pypillometry_conf.py', subjects=None)[source]

Read a study from a local directory using the configuration file.

Parameters:
  • path (str) – Local path where the study data is stored

  • config_file (str, optional) – Name of the configuration file. Default is “pypillometry_conf.py”

  • subjects (list[str], optional) – List of subject IDs to load. If None, all subjects will be loaded. If a subject ID is provided that doesn’t exist in the data, it will be skipped.

Returns:

  • study_data (dict) – Dictionary containing the loaded study data

  • config (module) – Module containing the configuration (pypillometry_conf.py imported as a module)

pypillometry.io.load_study_osf(osf_id, path, subjects=None, force_download=False, config_file='pypillometry_conf.py', session=None)[source]

Read a study from OSF using the configuration file. Example: https://osf.io/p2u74/

Parameters:
  • osf_id (str) – The OSF project ID

  • path (str) – Local path where files should be downloaded/stored

  • subjects (list[str], optional) – List of subject IDs to load. If None, all subjects will be loaded. If a subject ID is provided that doesn’t exist in the data, it will be skipped.

  • force_download (bool, optional) – If True, force re-download even if files exist locally. Default False.

  • config_file (str, optional) – Name of the configuration file. Default is “pypillometry_conf.py”

  • session (requests.Session, optional) – Authenticated session for accessing private projects. If None, uses unauthenticated requests.

Returns:

  • study_data (dict) – Dictionary containing the loaded study data

  • config (module) – Module containing the configuration (pypillometry_conf.py imported as a module)

pypillometry.io.osf_authenticate(access_token, validate=True, session=None, timeout=10.0)[source]

Authenticate against the OSF API using a personal access token.

Parameters:
  • access_token (str) – Personal access token generated on OSF.

  • validate (bool, optional) – If True (default), verify the token by calling /v2/users/me/.

  • session (requests.Session, optional) – Existing session to configure. If None, a new session is created.

  • timeout (float, optional) – Timeout (in seconds) for the validation request when validate is True.

Returns:

Session configured with the OSF bearer token.

Return type:

requests.Session

Raises:

ValueError – If no access token is provided or validation fails.

Read an Eyelink file/URL and return the object returned by the “eyelinkio” package.

Parameters:
  • source (str) – filename of the Eyelink file or URL

  • cache_file (str, optional) – filename to cache the file in case it is downloaded from a URL

  • force_download (bool, optional) – if True, force re-download even if file exists locally

  • session (requests.Session, optional) – requests session to use for the download.

Returns:

object returned by the “eyelinkio” package

Return type:

object

pypillometry.io.write_pickle(obj, fname)[source]

Store any Python object in a file using pickle.

Parameters:
  • obj (object) – object to save

  • fname (str) – filename to save to

example_data.py

Example datasets for pypillometry.

This module provides example datasets for pypillometry. The datasets are used in the documentation and for testing purposes. Most of them are stored on OSF: https://osf.io/p2u74/

pypillometry.example_data.get_available_datasets()[source]

Return available example datasets.

Returns a dictionary that displays as a nicely formatted pandas DataFrame in Jupyter notebooks but can be used as a normal dict otherwise.

Returns:

A dictionary (subclass of dict) containing all dataset metadata. When displayed in Jupyter, it will render as a pandas DataFrame with columns for Dataset name, Type, and Description.

Return type:

DatasetDict

Examples

>>> datasets = get_available_datasets()
>>> # In Jupyter, this displays as a nice DataFrame
>>> datasets
>>> # But you can still use it like a normal dict
>>> datasets['rlmw_002']
pypillometry.example_data.get_example_data(key)[source]

Load example data for a given example (see example_datasets).

Parameters:

key (str) – Key of the example dataset. Available keys are in the dictionary example_datasets.

Returns:

The example dataset as an EyeData, GazeData or PupilData object.

Return type:

EyeData, GazeData or PupilData

Indices and tables