Metadata-Version: 2.4
Name: pupilio
Version: 1.5.2
Summary: Pupilio Library
Author-email: Pupilio <zhugc2016@gmail.com>
License-Expression: CC-BY-4.0
Project-URL: Homepage, https://github.com/GanchengZhu/Pupilio
Project-URL: Repository, https://github.com/GanchengZhu/Pupilio
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: Microsoft :: Windows
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: pygame
Requires-Dist: opencv-python
Provides-Extra: psychopy
Requires-Dist: psychopy; extra == "psychopy"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

<style>
  table th { text-align: left !important; }
</style>

<div align="left">

# Pupil.IO Python Integration 

</div>

**pupilio** is a lightweight Python SDK for the Pupil.IO eye-trackers developed by Hangzhou Shenning Technology Co., Ltd. It offers a user-friendly interface that covers core eye-tracking functions like data recording, calibration,  validation, and real-time access to gaze data. **"pupilio"** seamlessly integrates with popular platforms such as PsychoPy and PyGame, it enables quick development of eye-tracking studies.

## The Pupil.IO eye-tracker
<div align="left">
  <a href="https://raw.githubusercontent.com/GanchengZhu/Pupilio/refs/heads/master/docs/_static/images/intro/about/pupilio_c.PNG">
    <img width="390" height="351" src="https://raw.githubusercontent.com/GanchengZhu/Pupilio/refs/heads/master/docs/_static/images/intro/about/pupilio_c.PNG">
  </a>
</div>

[Pupil.IO](https://www.deep-gaze.com/) is a high-speed, high-precision eye-tracking system featuring an all-in-one (AIO) plug-and-play design that is ideal for both scientific research and clinical applications. With minimal setup (just power on and start tracking), it delivers lab-grade accuracy in a compact, user-friendly form factor.

- **Precision Tracking**: Capture high-frequency eye movement and pupil dynamics with lab-grade accuracy.
- **Seamless Compatibility**: Native integration with PsychoPy, PyGame, and other Python experimental platforms.
- **Multi-Modal Synchronization**: Native support for LabStreamingLayer (LSL) to synchronize gaze, pupil dynamics, and event markers with EEG, fNIRS, and EMG via LabRecorder.
- **Intuitive Workflow**: Simplified calibration, validation, and recording with minimal setup.

### Specifications
| Specifications                 | AIO <br/>(Commercial Use) | PRO<br/>(Research)    | DVS-2K¹<br/>(Premier Research) |
|:-------------------------------|:--------------------------|:----------------------|:-------------------------------|
| Sampling Rate                  | 200 Hz                    | 200 Hz / 400 Hz       | 2000 Hz                        |
| Tracking Accuracy              | 0.5-1.0 deg               | 0.3-0.8 deg           | 0.3-0.8 deg                    |
| Spatial Precision²             | 0.01/0.07 deg             | 0.02/0.09 deg         | 0.02 deg                       |
| System Latency³                | 12.16 ms / SD = 1.22      | 4.91 ms / SD = 1.42   | 2.5 ms                         |
| Tracking Algorithm             | Neural Network            | Neural Network        | Neural Network                 |
| Development Support            | C++/Python/Matlab         | C++/Python/Matlab     | C++/Python/Matlab              |
| Operating System               | Windows 11                | Windows 11            | Windows 11                     |
| Head Support                   | No                        | No                    | Yes                            |
| Head Box⁴                      | 28 x 28 cm @ 70 cm        | 28 x 28 cm @ 70 cm    | -                              |
| Psychology Experiment Software | PsychoPy/PsychToolBox     | PsychoPy/PsychToolBox | PsychoPy/PsychToolBox          |
| Research Support               | No                        | Yes                   | Yes                            |

<sup>1</sup> DVS-2K edition available in Q4 2026. Final specifications subject to change.<br>
<sup>2</sup> S2S-RMS, measured using artificial eyes with the filter turned on/off.<br>
<sup>3</sup> Measured against an industry-standard eye-tracker operating at 2000 Hz.<br>
<sup>4</sup> When operating at 200 Hz and both eyes are reliably tracked at a camera-to-eye distance of 70 cm.

## Installation

Currently, all eye trackers shipped with Pupilio are pre-configured with the necessary Pupilio Python packages. If we need to upgrade this package, please enter the following command in the command prompt or PowerShell window:

```bash
pip install -U pupilio
```


## Quick Start
Here is a simple example to get started with Pupilio:

```python
# load PyGame library
import pygame
from pygame.locals import FULLSCREEN, HWSURFACE

# initialize PyGame
pygame.init()
# define the scree size
scn_width, scn_height = (1920, 1080)
# set a fullscreen mode with the above size
win = pygame.display.set_mode((scn_width, scn_height), FULLSCREEN|HWSURFACE)

# load Pupilio library
from pupilio import Pupilio

# instantiate a connection to the tracker
pupil_io = Pupilio()

# create a task session, and set a session name. 
# The session name must contain only letters, digits or underscores without any special characters.
pupil_io.create_session(session_name="quick_start")

# calibration and validation (recommended)
# set 'validate' to True if we would like to verify the calibration results
pupil_io.calibration_draw(screen=win, validate=True)

# start retrieving gaze
pupil_io.start_sampling()

# hang the main thread for 5 seconds by game
# eye tracking sampling are running on the background thread
pygame.time.wait(5 * 1000)

# stop eye tracking sampling
pupil_io.stop_sampling()

# sleep for 100 ms to capture ending samples
pygame.time.wait(100)

# save eye movement data
pupil_io.save_data("eye_movement.csv")

# release the tracker instance
# clean up Pupilio resources
pupil_io.release()

# quit pygame
pygame.quit()
```

## Multi-Modal Synchronization (LabStreamingLayer)

Pupilio natively supports **LabStreamingLayer (LSL)** to synchronize eye-tracking data (gaze, pupil diameter, triggers) with EEG, fNIRS, and other biosensors via [LabRecorder](https://github.com/labstreaminglayer/App-LabRecorder).

```python
from pupilio import Pupilio, DefaultConfig

config = DefaultConfig()
config.enable_lsl = True
config.lsl_stream_mode = "standard"  # 12 channels (or "full" for 39 channels)

pupil_io = Pupilio(config=config)
pupil_io.create_session("eeg_eyetracking_session")

# Start sampling (LSL starts broadcasting automatically)
pupil_io.start_sampling()

# Forward numeric triggers to both LSL continuous Gaze (channel 11) & discrete Markers stream
pupil_io.set_trigger(101)

# Broadcast custom semantic string annotations
pupil_io.send_lsl_marker("STIMULUS_ONSET")

# Stop sampling (LSL stops automatically)
pupil_io.stop_sampling()
pupil_io.release()
```

For detailed stream specifications and integration with EEGLAB / MNE, see the [LabStreamingLayer Integration Guide](docs/start/lsl_guide.md) or [GitHub Wiki](docs/wiki/LabStreamingLayer-Integration.md).

## Preprocessing for eye tracking data

Detect fixations and saccades using the **I-DT** (Identification by Dispersion Threshold) algorithm. The I-DT algorithm identifies fixations as groups of consecutive samples where the dispersion (sum of x and y ranges) remains below a specified threshold for a minimum duration.

**Example:**

```python
import glob
import os

from pupilio import EventDetection

ed = EventDetection()

out_dir = 'output'
os.makedirs(out_dir, exist_ok=True)
f = open('error.txt', 'w')
for i in glob.glob(r'example.csv'):
    try:
        ed.detect(i, output_dir=out_dir, which_eye='right')
    except Exception as e:
        f.write(i + ',' + str(e) + '\n')
        f.flush()
```

## Documentation

Comprehensive documentation is available at Pupilio [Documentation](https://pupilio.readthedocs.io/en/latest/start/demo.html).

## Support

If you encounter any issues or have questions, please open an issue on GitHub or contact [zhugc2016@gmail.com](mailto:zhugc2016@gmail.com).

## License

Pupilio is a proprietary software developed by Hangzhou Shenning Technology Co., Ltd. All rights reserved. Unauthorized use, distribution, or modification is prohibited without explicit permission. For licensing inquiries, please contact [zhugc2016@gmail.com](mailto:zhugc2016@gmail.com).

## Acknowledgments
Pupilio is developed and maintained by Hangzhou Shenning Technology Co., Ltd. Special thanks to the community for their valuable feedback and support.
