Skip to content

Latest commit

 

History

17 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

py-pupil

py-pupil is a Python GUI and analysis toolkit for estimating mouse pupil size from DeepLabCut (DLC) tracking results. It loads DLC CSV/HDF5 files, fits ellipses to pupil and eye keypoints, detects blinks, performs temporal processing and normalization, and exports analysis-ready time-series data.

The typical workflow is:

  1. Preprocess eye videos so that the pupil boundary is easy to track.
  2. Run DeepLabCut and export filtered tracking results as CSV or HDF5.
  3. Analyze the DLC output with py-pupil.
  4. Export pupil area, blink masks, normalized traces, metadata, and optional overlay videos.
  5. Use the exported CSV files for plotting, epoch analysis, peri-event analysis, or downstream statistics.

Features

  • Load DeepLabCut CSV and HDF5 outputs with multi-level headers
  • Fit ellipses to pupil and eye contour keypoints
  • Filter low-confidence points using DLC likelihood values
  • Optional video-based edge refinement for pupil boundary detection
  • Blink detection, blink masking, interpolation, and temporal smoothing
  • Temporal smoothing of ellipse parameters
    • Kalman filter
    • Independent smoothing
    • Moving average
  • Pupil area smoothing
    • Savitzky-Golay
    • Butterworth
    • Median
    • Gaussian
  • Multiple normalization methods
    • Raw area
    • Eye ratio
    • Global z-score
    • Baseline z-score
    • Percent baseline change
    • Min-max scaling
    • Robust z-score
  • GUI-based analysis with plots and summary statistics
  • Batch processing through the Queue tab
  • Export to CSV, JSON metadata, blink-event CSV, and pickle (.pkl)
  • Overlay video export with pupil ellipse, blink indicators, timestamps, and time-series plots
  • Advanced epoch and peri-event analysis

Requirements

Recommended environment:

  • Python 3.10 or later
  • Windows, macOS, or Linux
  • DeepLabCut tracking output in CSV or HDF5 format
  • The original or preprocessed video file, if you want FPS auto-detection, video refinement, or overlay video export

This repository currently does not include packaging metadata such as pyproject.toml, setup.py, or requirements.txt, so install the required packages manually:

pip install numpy pandas scipy pyyaml opencv-python PyQt6 pyqtgraph h5py tables

For a minimal GUI-only setup:

pip install numpy pandas scipy pyyaml PyQt6 pyqtgraph

Additional notes:

  • opencv-python is required for video loading, image refinement, and overlay video export.
  • tables is required for reading DLC HDF5 files (.h5, .hdf5).
  • pyqtgraph is required for interactive GUI plots.

Installation

git clone https://github.com/mi2e-K/py-pupil.git
cd py-pupil

python -m venv .venv

Activate the virtual environment.

Windows PowerShell:

.venv\Scripts\Activate.ps1

macOS / Linux:

source .venv/bin/activate

Install dependencies:

pip install --upgrade pip
pip install numpy pandas scipy pyyaml opencv-python PyQt6 pyqtgraph h5py tables

Run the GUI

From the repository root:

python -m pupil_analysis.gui.app

You can also launch the GUI from Python:

from pupil_analysis.gui import run_gui

run_gui()

Input data

DeepLabCut CSV / HDF5

py-pupil expects standard DeepLabCut output files with a multi-level header containing scorer, bodypart, and coordinate levels.

For most analyses, use the filtered DLC output file, usually named like:

*_filtered.csv

When running DeepLabCut, it is recommended to enable:

  • Save result(s) as csv
  • Filter predictions

Default keypoint names

By default, py-pupil expects the following bodypart names.

Pupil

pupil_Top
pupil_Top-right
pupil_Right
pupil_Bottom-right
pupil_Bottom
pupil_Bottom-left
pupil_Left
pupil_Top-left

Eye

eye_Top
eye_Top-right
eye_Right
eye_Bottom-right
eye_Bottom
eye_Bottom-left
eye_Left
eye_Top-left

If these exact names are not found, py-pupil attempts to auto-detect bodyparts that contain pupil or eye in their names. For stable ellipse fitting, label at least four points per contour; eight points per pupil and eye contour are recommended.


Quick start: GUI analysis

  1. Launch the GUI:

    python -m pupil_analysis.gui.app
  2. Open the Analysis tab.

  3. Select a DLC CSV or HDF5 file.

    • Usually, this should be the filtered DLC CSV file.
  4. Optionally select the corresponding video file.

    • This is used for FPS auto-detection, image refinement, and overlay video export.
  5. Check the analysis settings:

    • Likelihood threshold
    • Blink detection
    • Ellipse temporal smoothing
    • Interpolation
    • Area smoothing
    • Baseline duration
    • Normalization methods
  6. Click Run Analysis.

  7. Review the plots, summary, frame counts, valid-frame count, blink count, and pupil-area statistics.

  8. Export results with Export CSV... or Export All....


Queue / batch processing

The Queue tab is designed for processing multiple files.

Typical batch workflow:

  1. Add one or more DLC CSV/HDF5 files as analysis tasks.
  2. Review the analysis settings.
  3. Run the queue to analyze all pending files.
  4. Save analysis results as .pkl files.
  5. Add video export tasks using saved .pkl results and matching video files.
  6. Run the queue again to create overlay videos.

The queue table shows task name, task type, status, progress, and error messages.


Output files

The GUI and exporter can produce the following files.

File Description
*_data.csv Frame-by-frame pupil area, normalized traces, quality values, and blink mask
*_metadata.json Analysis summary, statistics, processing notes, blink events, and normalization metadata
*_blinks.csv Detected blink events with frame/time ranges and confidence values
*.pkl Serialized AnalysisResult object for later reuse
Overlay video Video with pupil ellipse, optional eye ellipse, blink indicator, timestamp, and trace plot

Common CSV columns include:

Column Description
frame_index Frame number
timestamp Time in seconds
pupil_area_raw Raw pupil ellipse area
eye_area_raw Raw eye ellipse area
pupil_area_processed Interpolated and/or smoothed pupil area
eye_area_processed Interpolated and/or smoothed eye area
pupil_eye_ratio Pupil area divided by eye area
pupil_z_global Global z-score of pupil area
pupil_z_baseline Baseline-window z-score of pupil area
pupil_percent_baseline Percent change from baseline
quality Frame-level processing quality
is_blink Blink mask; 1 indicates blink/artifact frames

Python API

You can run the analysis without the GUI.

from pupil_analysis.pipeline.analyzer import PupilAnalyzer, AnalysisConfig
from pupil_analysis.pipeline.exporter import ResultExporter

config = AnalysisConfig(
    min_likelihood=0.3,
    blink_detection=True,
    interpolate_blinks=True,
    max_interpolation_gap=10,
    smooth_data=True,
    smoothing_method="savgol",
    ellipse_smoothing=True,
    ellipse_smoothing_method="kalman",
    baseline_seconds=120.0,
    normalization_methods=[
        "raw",
        "eye_ratio",
        "z_global",
        "z_baseline",
        "percent_baseline",
    ],
)

analyzer = PupilAnalyzer(config=config)

result = analyzer.analyze_from_dlc(
    dlc_path="path/to/videoDLC_resnet_filtered.csv",
    video_path="path/to/preprocessed_video.avi",  # optional
)

exporter = ResultExporter(output_dir="results")
exporter.export(result, basename="sample01")

Save and reload an analysis result:

result.save("results/sample01.pkl")

from pupil_analysis.pipeline.analyzer import AnalysisResult

loaded = AnalysisResult.load("results/sample01.pkl")

Advanced analysis

The Advanced Analysis tab provides epoch-based and peri-event analysis tools for an already computed AnalysisResult.

Available analyses include:

  • Epoch definition
    • baseline
    • control
    • stimulation
    • recovery
  • Epoch statistics
    • mean
    • standard deviation
    • SEM
    • median
    • minimum / maximum
  • Change from baseline
  • Percent change from baseline
  • Peri-event analysis aligned to event times
  • Mean trace and SEM across events

Example epoch design:

Epoch Time
Baseline 0-120 s
Yellow light 120-180 s
Recovery 1 180-240 s
Blue light 240-300 s
Recovery 2 300-360 s

Overlay video export

Overlay video export can add the following elements to the source video:

  • Fitted pupil ellipse
  • Optional eye ellipse
  • Pupil center marker
  • Rolling time-series plot
  • Current-frame marker on the plot
  • Timestamp
  • Blink indicator
  • Optional captions

Video export requires opencv-python.

pip install opencv-python

The input video should be the same video used for DLC tracking or an exactly corresponding preprocessed video. If the crop, rotation, flip, scale, or FPS differs from the DLC input video, the overlay may be misaligned.


Video preprocessing tips

DLC tracking quality strongly affects pupil analysis quality.

Recommended preprocessing steps:

  • Crop the video so that the eye remains inside the region of interest across all frames.
  • Use horizontal flip if needed to keep orientation consistent across sessions.
  • Rotate the video so that the eye is approximately horizontal.
  • Adjust brightness and contrast so that the pupil and eye boundary are clear.
  • Use moderate sharpening only when it improves boundary visibility.
  • Avoid excessive denoising or contrast enhancement that destroys the pupil boundary.
  • If upscaling is useful, use a consistent scale factor such as 4x.
  • Use DLC filtered predictions for downstream pupil analysis.

Troubleshooting

The GUI does not start

Make sure PyQt6 and pyqtgraph are installed:

pip install PyQt6 pyqtgraph

Run the command from the repository root:

python -m pupil_analysis.gui.app

ModuleNotFoundError: pupil_analysis

Run scripts from the repository root, or add the repository path to PYTHONPATH.

Windows PowerShell:

$env:PYTHONPATH = (Get-Location)

macOS / Linux:

export PYTHONPATH=$(pwd)

HDF5 files cannot be loaded

Install tables:

pip install tables

Overlay video export fails

Install OpenCV:

pip install opencv-python

Also confirm that the selected video corresponds to the DLC tracking file.

Most output values are NaN

Check the following:

  • You are using the DLC filtered CSV/HDF5 output.
  • Pupil bodypart names contain pupil, or match the expected default names.
  • There are enough valid keypoints for ellipse fitting.
  • The likelihood threshold is not too high.
  • The pupil boundary is visible in the video.
  • Video preprocessing did not blur or saturate the pupil boundary.

The overlay is shifted or rotated

Use the same video that was used for DLC analysis. If DLC was run on a cropped, rotated, flipped, resized, or otherwise preprocessed video, use that same video for overlay export.


Repository structure

pupil_analysis/
  core/                 # Data classes and exceptions
  config/               # Dataclass-based settings and YAML support
  io/                   # DLC CSV/HDF5 and video input/output
  geometry/             # Ellipse fitting
  refinement/           # Video-based edge refinement
  temporal/             # Blink detection, interpolation, smoothing
  normalization/        # Normalization methods and pipeline
  pipeline/             # PupilAnalyzer and result exporters
  gui/                  # PyQt6 GUI, queue, video export, advanced analysis

License

This project is licensed under the MIT License. See LICENSE for details.


Citation / acknowledgement

If you use this tool in published work, please acknowledge both DeepLabCut and this repository.

About

pupil analysis

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages