Signal Analysis

class meyelens.analysis.AdaptiveGazeFilter(min_cutoff=0.8, beta=0.08, d_cutoff=1.0, jump_reset=None)[source]

Bases: object

Adaptive gaze filter for live gaze pointer smoothing.

It uses a One Euro filter: - strong smoothing when gaze is stable - weaker smoothing when gaze moves quickly

Parameters:
  • min_cutoff – Base smoothing. Lower = smoother during fixation, but more lag. Try 0.6 to 1.2.

  • beta – Motion adaptation. Higher = faster response during eye movements. Try 0.02 to 0.15.

  • d_cutoff – Smoothing applied to velocity estimate. Usually 1.0 is fine.

  • jump_reset – If prediction jumps more than this distance, optionally reset the filter. Useful for very large gaze shifts or recovery from bad samples. In PsychoPy norm units, try 0.5 or None.

Bases: object

Blink cleaner for pupil traces.

Main logic

A sample is marked as blink/artifact if:

abs(derivative) / max(abs(derivative)) > threshold

or, if remove_zeros=True:

signal == zero_value

Then flankers are added around the detected samples. The detected samples are replaced with NaN and interpolated.

Main use

deblink = DeBlink(threshold=0.25, flankers=5)

pupil_clean = deblink.clean(pupil_area) blink_mask = deblink.get_blink_mask(pupil_area) diagnostics = deblink.get_diagnostics(pupil_area)

clean(signal)[source]

Return only the cleaned pupil signal.

Return the final blink/artifact mask.

True means that the sample is marked as blink/artifact and will be interpolated.

get_derivative_mask(signal)[source]

Return the blink/artifact mask based only on the derivative.

get_zero_mask(signal)[source]

Return the mask for zero-valued samples.

If remove_zeros=False, this returns an all-False mask.

get_diagnostics(signal)[source]

Return intermediate arrays useful for plotting/debugging.

clean_dataframe(df, column='pupil_area', output_column=None, blink_column=None, zero_column=None, derivative_column=None)[source]

Return a copy of df with a cleaned pupil column.

Parameters:
  • df – Input pandas DataFrame.

  • column – Input signal column.

  • output_column – Output cleaned signal column. If None, uses f”{column}_clean”.

  • blink_column – Optional output column for the final blink mask.

  • zero_column – Optional output column for zero-valued samples.

  • derivative_column – Optional output column for abs(derivative) / max(abs(derivative)).

static compute_derivative(signal)[source]

Compute derivative while preserving signal length.

np.gradient is used instead of np.diff so the derivative and mask have the same length as the original signal.

static normalize_by_max(x)[source]

Normalize a non-negative signal by its maximum.

Intended for abs(derivative):

0 = no change 1 = largest detected change

static add_flankers(mask, flankers)[source]

Expand a boolean mask by N samples on each side.

interpolate(signal_with_nan)[source]

Interpolate NaN samples.

plot_diagnostics(signal, time=None, show_clean=True)[source]

Plot the pupil trace, cleaned trace, derivative, threshold, and mask.

Parameters:
  • signal – One-dimensional pupil trace.

  • time – Optional time vector. If None, sample index is used.

  • show_clean – If True, plot the cleaned interpolated trace.

class meyelens.analysis.Filters(fs, order=4, method='sos')[source]

Bases: object

Frequency filter for pupil traces.

Supports:
  • lowpass

  • highpass

  • bandpass

Main use

filt = PupilFilter(fs=30)

pupil_low = filt.lowpass(pupil, cutoff=4.0) pupil_high = filt.highpass(pupil, cutoff=0.05) pupil_band = filt.bandpass(pupil, lowcut=0.05, highcut=4.0)

param fs:

Sampling frequency in Hz.

type fs:

float

param order:

Butterworth filter order.

type order:

int

param method:

“sos” or “ba”.

“sos” is recommended because it is more numerically stable.

type method:

str

lowpass(signal, cutoff)[source]

Lowpass filter.

Keeps frequencies below cutoff.

highpass(signal, cutoff)[source]

Highpass filter.

Keeps frequencies above cutoff.

bandpass(signal, lowcut, highcut)[source]

Bandpass filter.

Keeps frequencies between lowcut and highcut.

class meyelens.analysis.MeyeReader(path, sep=';', comment='#')[source]

Bases: object

Minimal reader for files created with MeyeRecorder.

The path must be provided explicitly.

Expected file format

# metadata_key: metadata_value # metadata_key: metadata_value frame_index;t_call;t_frame;…;trg1;trg2;… 0;0.001;0.010;…

Basic usage

reader = MeyeReader(“path/to/recording.txt”)

df = reader.data metadata = reader.metadata

reader.print_summary()

copy()[source]

Return a copy of the recording table.

columns()[source]

Return the column names.

get_metadata()[source]

Return a copy of the metadata dictionary.

print_summary()[source]

Print file, metadata, and column information.

class meyelens.analysis.TrialEpochs(signal, time, triggers)[source]

Bases: object

Extract stimulus-locked epochs from one signal and one or more trigger traces.

This class does not perform trial rejection or signal cleaning. Clean/filter the signal before passing it here.

Example

trialer = TrialEpochs(
    signal=pupil_signal,
    time=time,
    triggers={
        "standard": trg_standard,
        "oddball": trg_oddball,
        "distractor": trg_distractor,
    },
)

epochs = trialer.extract(
    tmin=-1.0,
    tmax=4.0,
    baseline=(-1.0, 0.0),
    transform="zscore",
)

Transform options

  • "none": raw epoch.

  • "delta": epoch minus baseline mean.

  • "percent": percent change from baseline mean.

  • "zscore": baseline-normalized z-score.

extract(tmin=-1.0, tmax=4.0, baseline=None, transform='none', trigger_value=1, edge='rising', n_points=300, exclude_first=0, exclude_last=0)[source]

Extract epochs for all trigger traces.

Parameters:
  • tmin – Epoch window in seconds relative to trigger onset.

  • tmax – Epoch window in seconds relative to trigger onset.

  • baseline – None or tuple, for example (-1.0, 0.0). Baseline window is relative to trigger onset.

  • transform – “none”, “delta”, “percent”, or “zscore”.

  • trigger_value – Trigger value marking stimulus onset.

  • edge"rising" detects transitions into the trigger value. "level" detects every sample equal to the trigger value.

  • n_points – Number of points in the interpolated epoch time base.

  • exclude_first – Number of first detected events to exclude for each condition.

  • exclude_last – Number of last detected events to exclude for each condition.

Returns:

Contains the common epoch time base and a conditions mapping. Each condition stores epochs, event indices, event times, mean, SEM, and trial count. With one trigger, those fields are also exposed at the top level.

Return type:

dict

get_event_times(trigger_name=None, trigger_value=1, edge='rising')[source]

Return event times for one trigger.

get_event_indices(trigger_name=None, trigger_value=1, edge='rising')[source]

Return event indices for one trigger.

static apply_baseline_transform(epoch, epoch_time, baseline=None, transform='none')[source]

Apply baseline correction or transformation to one epoch.

static find_events(trigger, value=1, edge='rising')[source]

Find trigger events.

edge=”rising”:

detect transition from not-value to value.

edge=”level”:

detect every sample equal to value.