Metadata-Version: 2.4
Name: gpbiometricspy
Version: 0.1.4
Summary: Python port of gpbiometrics 2.0.0 for Gazepoint biometric workflows
Author: Stefanos Balaskas
License-Expression: MIT
Project-URL: Homepage, https://stefanosbalaskas.github.io/gpbiometricspy/
Project-URL: Repository, https://github.com/stefanosbalaskas/gpbiometricspy
Project-URL: Documentation, https://stefanosbalaskas.github.io/gpbiometricspy/
Project-URL: RReference, https://stefanosbalaskas.github.io/gpbiometrics/
Project-URL: RReferenceDOI, https://doi.org/10.5281/zenodo.21434608
Project-URL: DOI, https://doi.org/10.5281/zenodo.22150872
Project-URL: PreviousVersionDOI, https://doi.org/10.5281/zenodo.22313884
Project-URL: Issues, https://github.com/stefanosbalaskas/gpbiometricspy/issues
Project-URL: PyPI, https://pypi.org/project/gpbiometricspy/
Keywords: gazepoint,eye-tracking,eda,gsr,hrv,ppg,physiology,pupillometry
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.26
Requires-Dist: pandas>=2.1
Requires-Dist: scipy>=1.11
Requires-Dist: matplotlib>=3.8
Provides-Extra: heartpy
Requires-Dist: heartpy>=1.2.7; extra == "heartpy"
Requires-Dist: setuptools<82,>=77; extra == "heartpy"
Provides-Extra: biosppy
Requires-Dist: biosppy>=2.2.4; extra == "biosppy"
Requires-Dist: peakutils>=1.3.4; extra == "biosppy"
Provides-Extra: pyhrv
Requires-Dist: pyhrv>=0.5.0; extra == "pyhrv"
Requires-Dist: peakutils>=1.3.4; extra == "pyhrv"
Requires-Dist: nolds<0.6.3; extra == "pyhrv"
Requires-Dist: setuptools<82,>=77; extra == "pyhrv"
Provides-Extra: neurokit
Requires-Dist: neurokit2>=0.2.13; extra == "neurokit"
Provides-Extra: mne
Requires-Dist: mne>=1.12.1; extra == "mne"
Provides-Extra: lsl
Requires-Dist: pylsl>=1.18.2; extra == "lsl"
Requires-Dist: pyxdf>=1.17.5; extra == "lsl"
Provides-Extra: bayes
Requires-Dist: pymc>=6.3; extra == "bayes"
Provides-Extra: stats
Requires-Dist: statsmodels>=0.14; extra == "stats"
Provides-Extra: interop
Requires-Dist: heartpy>=1.2.7; extra == "interop"
Requires-Dist: setuptools<82,>=77; extra == "interop"
Requires-Dist: biosppy>=2.2.4; extra == "interop"
Requires-Dist: peakutils>=1.3.4; extra == "interop"
Requires-Dist: pyhrv>=0.5.0; extra == "interop"
Requires-Dist: nolds<0.6.3; extra == "interop"
Requires-Dist: neurokit2>=0.2.13; extra == "interop"
Requires-Dist: mne>=1.12.1; extra == "interop"
Requires-Dist: pylsl>=1.18.2; extra == "interop"
Requires-Dist: pyxdf>=1.17.5; extra == "interop"
Requires-Dist: statsmodels>=0.14; extra == "interop"
Provides-Extra: studio
Requires-Dist: shiny<2,>=1.7; extra == "studio"
Provides-Extra: studio-test
Requires-Dist: shiny<2,>=1.7; extra == "studio-test"
Requires-Dist: pytest-playwright<1,>=0.9; extra == "studio-test"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.6; extra == "docs"
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.27; extra == "docs"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-cov>=5; extra == "dev"
Requires-Dist: ruff>=0.9; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: twine>=6; extra == "dev"
Dynamic: license-file

<p align="center">
  <img src="https://raw.githubusercontent.com/stefanosbalaskas/gpbiometricspy/main/docs/assets/python-suite-logo.png" width="260" alt="Python Suite research packages logo">
</p>

<h1 align="center">gpbiometricspy</h1>

<p align="center">
  <strong>Scientific Python infrastructure and a Shiny application for EDA/SCR, PPG/HRV, pupil, gaze, AOI, synchronization, QC, and multimodal Gazepoint research.</strong>
</p>

<p align="center">
  <a href="https://pypi.org/project/gpbiometricspy/"><img alt="PyPI" src="https://img.shields.io/pypi/v/gpbiometricspy.svg"></a>
  <a href="https://pypi.org/project/gpbiometricspy/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/gpbiometricspy.svg"></a>
  <a href="https://github.com/stefanosbalaskas/gpbiometricspy/releases/latest"><img alt="GitHub release" src="https://img.shields.io/github/v/release/stefanosbalaskas/gpbiometricspy"></a>
  <a href="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/tests.yml"><img alt="Tests" src="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/tests.yml/badge.svg?branch=main"></a>
  <a href="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/branch-coverage.yml"><img alt="Branch audit" src="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/branch-coverage.yml/badge.svg?branch=main"></a>
  <a href="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/docs.yml"><img alt="Docs" src="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/docs.yml/badge.svg?branch=main"></a>
  <a href="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/studio.yml"><img alt="Studio" src="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/studio.yml/badge.svg?branch=main"></a>
  <a href="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/studio-e2e.yml"><img alt="Studio browser E2E" src="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/studio-e2e.yml/badge.svg?branch=main"></a>
  <a href="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/studio-production.yml"><img alt="Studio production" src="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/studio-production.yml/badge.svg?branch=main"></a>
  <a href="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/codeql.yml"><img alt="CodeQL" src="https://github.com/stefanosbalaskas/gpbiometricspy/actions/workflows/codeql.yml/badge.svg?branch=main"></a>
  <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg"></a>
  <a href="https://doi.org/10.5281/zenodo.22150872"><img alt="DOI" src="https://zenodo.org/badge/DOI/10.5281/zenodo.22150872.svg"></a>
  <a href="https://doi.org/10.3390/signals7050086"><img alt="gpbiometrics paper" src="https://img.shields.io/badge/gpbiometrics%20paper-10.3390%2Fsignals7050086-blue.svg"></a>
</p>

<p align="center">
  <a href="https://stefanosbalaskas.github.io/gpbiometricspy/"><strong>Documentation</strong></a> ·
  <a href="https://stefanosbalaskas.github.io/gpbiometricspy/studio/"><strong>Studio</strong></a> ·
  <a href="https://stefanosbalaskas.github.io/gpbiometricspy/workflows/"><strong>Workflow map</strong></a> ·
  <a href="https://stefanosbalaskas.github.io/gpbiometricspy/api/"><strong>Browse API</strong></a> ·
  <a href="https://stefanosbalaskas.github.io/gpbiometricspy/plot-gallery/"><strong>Plot gallery</strong></a> ·
  <a href="#citation"><strong>Citation</strong></a>
</p>

`gpbiometricspy` is scientific Python infrastructure for Gazepoint and multimodal psychophysiology workflows spanning EDA/SCR, PPG/HRV, pupil, gaze/AOI, event alignment, quality control, statistics, interoperability, and reproducible reporting. It is the Python counterpart of **gpbiometrics**, using the supplied **gpbiometrics 2.0.0** source release as a frozen semantic reference. **gpbiometricspy Studio** adds a Shiny for Python application layer that calls the same public package API rather than reimplementing the scientific methods.

| Status | Current state |
|---|---|
| Stable release | **0.1.4** |
| Release date | **2026-09-06** |
| Frozen semantic reference | **gpbiometrics 2.0.0** |
| API parity | **406 / 406 implemented · 0 pending** |
| Validation | **557 tests · 100.00% statements · 99.6604% raw branches · 0 unaudited branch debt** |
| Studio | **11 application workflows · smoke + Chromium E2E + production CI** |
| Supported Python | **3.11–3.14** |

## What you get

- **Complete frozen API contract:** all **406 / 406** exported R functions are implemented and registered, with **0 pending exports**.
- **Literal whole-package statement coverage:** **557 tests**, **10,316 statements**, **0 missed**, and a CI statement floor of **100%**.
- **Audited branch accounting:** raw branch coverage is **5,575 / 5,594 = 99.6604%**; the remaining **19** arcs are frozen as structural/caller-dominated debt, with **0 unexpected**, **0 stale**, and **0 unaudited** missing branches under CI.
- **gpbiometricspy Studio:** a stateful Shiny interface for intake/QC, annotation, EDA/SCR, PPG/HRV, pupil, gaze/fixation/AOI, events/alignment, multimodal analysis, statistics/modelling, and reporting/reproducibility.
- **Scientific-domain navigation:** the documentation groups the API into **8 research domains** while preserving the complete alphabetical 406-function reference.
- **Executable learning material:** **26** frozen-R article/vignette companions are paired with Python workflows, examples, and generated figures.
- **Reproducible public demo data:** a fully synthetic kiosk dataset with **36 participants and 69,120 rows** ships with the package.
- **Deep validation layers:** independent R↔Python golden fixtures, optional-backend interoperability CI, privacy-preserving real-data validation, structural branch-debt enforcement, Studio browser/production CI, and frozen upstream provenance.

The project deliberately distinguishes **API completion** from an absolute claim that independent R and Python runtimes are numerically identical in every external-library/version combination. The frozen R implementation, tests, documentation, and article sources are retained in `reference/` so deeper parity can continue to be audited.

## Install

Install the current public release from PyPI:

```bash
python -m pip install gpbiometricspy
```

For optional scientific integrations:

```bash
python -m pip install "gpbiometricspy[interop]"
```

For a source checkout used in package development:

```bash
python -m pip install -e ".[dev]"
```

Individual extras are available for `heartpy`, `biosppy`, `pyhrv`, `neurokit`, `mne`, `lsl`, `bayes`, `stats`, `studio`, `studio-test`, `docs`, and `dev`.

## gpbiometricspy Studio

Studio is a repository/application layer over the public package API. In stable `0.1.4`, it is included in the Python distribution with installed launch commands.

From a source checkout:

```bash
git clone https://github.com/stefanosbalaskas/gpbiometricspy.git
cd gpbiometricspy
python -m pip install -e ".[studio]"
gpbiometricspy-studio
```

For the synthetic-only public boundary:

```bash
gpbiometricspy-studio-public
```

Or run directly during development:

```bash
shiny run --reload studio/app.py
```

The **full Studio** accepts research-data files and is intended for local use or an appropriately authenticated/private deployment. The **public-demo boundary** removes external upload controls and independently rejects server-side external-file consumers; it is designed for the bundled synthetic dataset only. See the [Studio guide](https://stefanosbalaskas.github.io/gpbiometricspy/studio/) and [`DEPLOYMENT.md`](DEPLOYMENT.md).

## Quick start

```python
import gpbiometricspy as gp

# Load the public synthetic kiosk demo distributed with the package.
data = gp.load_kiosk_demo()
print(data.shape)  # (69120, ...)

# Inspect biometric signal validity / availability.
validity = gp.summarise_gazepoint_biometric_validity(data)

# Extract TTL transitions.
events = gp.extract_gazepoint_ttl_events(data)

# Example native pyHRV-style workflow from IBI values.
hrv = gp.run_gazepoint_pyhrv_style(
    nni_ms=data.loc[data["IBI"].notna(), "IBI"].head(500).to_numpy() * 1000
)
```

The bundled kiosk demo is **fully synthetic** and is intended only for examples, testing, and reproducible workflow demonstrations.

## Explore the documentation

Start with the route that matches what you want to do:

- **[Documentation home](https://stefanosbalaskas.github.io/gpbiometricspy/)** — package overview, status, entry points, and validation story.
- **[gpbiometricspy Studio](https://stefanosbalaskas.github.io/gpbiometricspy/studio/)** — application map, full/public runtime boundaries, launch commands, reproducibility and deployment.
- **[Workflow map](https://stefanosbalaskas.github.io/gpbiometricspy/workflows/)** — choose a path based on the signals and events you recorded.
- **[Browse API by scientific domain](https://stefanosbalaskas.github.io/gpbiometricspy/api/)** — navigate the 406-function surface by research task rather than alphabetically.
- **[Complete 406-function reference](https://stefanosbalaskas.github.io/gpbiometricspy/api/reference/)** — exhaustive frozen export reference.
- **[Examples](https://stefanosbalaskas.github.io/gpbiometricspy/examples/)** — EDA/SCR, PPG/HRV, pupil/gaze/AOI, multimodal, QC/reporting, and interoperability examples.
- **[Articles and tutorials](https://stefanosbalaskas.github.io/gpbiometricspy/articles/)** — all 26 frozen R vignette/article companions, organized by scientific topic and backed by executable Python code.
- **[Plot gallery](https://stefanosbalaskas.github.io/gpbiometricspy/plot-gallery/)** — figures generated directly by the Python plotting API from bundled synthetic/public data.

## Scientific scope

The frozen `gpbiometrics 2.0.0` parity surface covers, among other areas:

- Gazepoint biometric file/folder import, schema detection, validation, and QC;
- EDA/GSR/SCR preprocessing, artifacts, response detection, windows, habituation/recovery, spectral and nonlinear descriptors, and external bridges;
- HR/IBI/HRV/PPG processing, pyHRV-style, HeartPy-style and BioSPPy-style workflows, nonlinear HRV, RQA/geometric metrics, and respiratory proxies;
- pupil, gaze, fixation, saccade, AOI, and event-locked multimodal workflows;
- TTL alignment, synchronization drift, LSL/XDF, MNE, and BIDS-oriented bridges;
- cluster permutation testing plus explicit guardrails for designs the frozen R package intentionally refuses;
- reproducibility, preregistration, audit trails, readiness checks, reporting, plots, workflow summaries, simulation, and synthetic smoke testing.

## Validation and parity

Development on `main` goes beyond the 406/406 export freeze. The repository includes independent R↔Python golden fixtures, floor/current optional-backend interoperability CI, executable article companions, platform/Python matrix testing, privacy-preserving real-data validation, branch-path auditing, and independent Studio unit/browser/production gates.

The current scientific development validation baseline is:

```text
R exports:                  406
Implemented exports:        406
Explicit pending:             0
Tests:                      557
Statements:              10,316
Missed statements:            0
Statement coverage:      100.00%
Statement CI floor:      100.00%
Branches:             5,575/5,594
Raw branch coverage:    99.6604%
Raw branch CI floor:    99.6000%
Audited structural arcs:       19
Unexpected missing arcs:        0
Stale structural entries:       0
Unaudited branch debt:           0
Audited branch accounting: 100.0000%
```

Raw branch coverage remains the literal coverage.py result; the structural-debt contract does **not** relabel it as 100%. Instead, CI requires the exact remaining 19 missing arcs to match the reviewed structural/caller-dominated ledger, so any new or stale uncovered path fails independently of the raw percentage.

Studio additionally runs Python 3.11/3.14 smoke tests, Chromium E2E tests, and deployment-style production/distribution checks. See [`VALIDATION.md`](VALIDATION.md) and the documentation site's validation material for the distinction between API parity, executable contract coverage, application validation, and deeper cross-runtime/backend evidence.

## Interpretation guardrails

`gpbiometricspy` preserves the conservative interpretation policy of the R package. Physiological and eye-tracking signals are measurements and derived features; they do **not** directly establish emotion, stress, cognition, preference, health status, or diagnosis. Pupil measurements remain sensitive to luminance and visual context, and respiration estimates derived from PPG or other surrogate channels are proxies unless independently validated.

<a id="citation"></a>
## Archival and citation

`gpbiometricspy 0.1.4` is the current stable release. Its version-specific Zenodo DOI will be recorded after Zenodo ingests the immutable `v0.1.4` GitHub release; the concept DOI identifies the evolving Python software record.

- **Software concept DOI:** [10.5281/zenodo.22150872](https://doi.org/10.5281/zenodo.22150872)
- **Previous version DOI (0.1.3):** [10.5281/zenodo.22313884](https://doi.org/10.5281/zenodo.22313884)
- **Earlier version DOI (0.1.2):** [10.5281/zenodo.22150873](https://doi.org/10.5281/zenodo.22150873)
- **Frozen R reference DOI:** [10.5281/zenodo.21434608](https://doi.org/10.5281/zenodo.21434608)
- **Published gpbiometrics R-package paper:** [10.3390/signals7050086](https://doi.org/10.3390/signals7050086)

For reproducible citation of analyses, cite the **version DOI** corresponding to the software release used. Use the **concept DOI** when referring to the evolving `gpbiometricspy` software family.

The peer-reviewed paper describing the original R package is:

> Balaskas, S. **gpbiometrics: An R Package for Reproducible Analysis and Reporting of Gazepoint Biometrics Exports.** *Signals* **2026**, *7*, 86. [https://doi.org/10.3390/signals7050086](https://doi.org/10.3390/signals7050086)

When using `gpbiometricspy`, cite the Python software release used in the analysis as well. The paper above documents the original R package and its scientific/software lineage; it does not replace the Python package's version-specific software citation.

The R DOI remains separate provenance and is recorded in `.zenodo.json` as `isDerivedFrom`; it is not the Python package DOI. GitHub citation metadata are maintained in [`CITATION.cff`](CITATION.cff).

## Reference precedence

When Python and explanatory prose disagree, parity work follows:

1. frozen `gpbiometrics 2.0.0` implementation;
2. frozen R tests;
3. formal Rd documentation;
4. vignettes/examples;
5. repository/site explanatory material.

See the documentation site source in `docs/`, the machine-readable export inventory in `reference/r-export-inventory.csv`, and [`VALIDATION.md`](VALIDATION.md) for the current release gates.
