Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
30eed17
docs: fix PyPI wording, MyST {doc} roles, and stale test description
IAmirKhani Jul 1, 2026
8773f9b
paper: finalize AI-usage disclosure wording
IAmirKhani Jul 1, 2026
8c4c9e9
paper: scope AI-usage disclosure to documentation and style refactoring
IAmirKhani Jul 1, 2026
bbc9681
fix(packaging): declare matplotlib dependency and trim sdist bloat
IAmirKhani Jul 2, 2026
2cfc31f
Update acknowledgments
IAmirKhani Jul 15, 2026
ffd5c68
Merge branch 'main' into joss-review-fixes
IAmirKhani Jul 15, 2026
fba9e48
update the README
IAmirKhani Jul 16, 2026
5fa3134
docs: describe the real public API in the package docstring
IAmirKhani Jul 17, 2026
7603ede
remove unused stats.summaries module
IAmirKhani Jul 17, 2026
fffbc1f
fix(simulations): honor the rng argument when generating spikes
IAmirKhani Jul 17, 2026
0f0de8d
fix(simulations): use .item() for scalar firing rates
IAmirKhani Jul 17, 2026
3674f72
release: bump to 0.0.2 and single-source the version
IAmirKhani Jul 17, 2026
5b7913f
docs: expand citation author lists and add 2021 framework paper
IAmirKhani Jul 18, 2026
671f118
Merge remote-tracking branch 'origin/main' into joss-review-fixes
IAmirKhani Jul 18, 2026
35ecb06
fix(api): warn when real LFP input is interpreted as phase
IAmirKhani Jul 21, 2026
7a9b27c
docs: clarify analytic LFP input requirements
IAmirKhani Jul 21, 2026
74a7951
docs(paper): correct LFP preprocessing description
IAmirKhani Jul 21, 2026
883e221
Improve paper figure layout and readability
IAmirKhani Jul 21, 2026
734a52b
Keep example figure within main paper text
IAmirKhani Jul 21, 2026
31e3f27
Add required JOSS sections and refine manuscript
IAmirKhani Jul 23, 2026
2825df4
Harden JOSS paper build workflow
IAmirKhani Jul 23, 2026
2774aeb
Merge main and resolve JOSS manuscript conflict
IAmirKhani Jul 23, 2026
7fd9c69
Fix typed statistical test configuration
IAmirKhani Jul 23, 2026
a2a3de6
Merge remote-tracking branch 'origin/main' into joss-review-fixes
IAmirKhani Aug 11, 2026
84322a6
update the bibliography and the pdf version of the manuscript
IAmirKhani Aug 11, 2026
5f7ae7e
paper: update bibliography and rebuild JOSS paper
IAmirKhani Aug 11, 2026
477c01a
Merge main and rebuild JOSS paper
IAmirKhani Aug 11, 2026
07bb9d2
docs: configure Read the Docs and restore JOSS sections
IAmirKhani Aug 11, 2026
a9431aa
docs: update repository links and revise paper materials
IAmirKhani Aug 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: 2

build:
os: ubuntu-24.04
tools:
python: "3.12"

sphinx:
configuration: docs/conf.py
fail_on_warning: false

python:
install:
- method: pip
path: .
extra_requirements:
- docs
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pip install pygpla
### From source

```bash
git clone https://github.com/CMC-lab/PyGPLA.git
git clone https://github.com/CMC-unit/PyGPLA.git
cd PyGPLA
pip install -e .
```
Expand Down
2 changes: 1 addition & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ If it’s a larger change, opening an issue first is usually better than startin
### Clone + environment

```bash
git clone https://github.com/CMC-lab/PyGPLA.git
git clone https://github.com/CMC-unit/PyGPLA.git
cd PyGPLA
python -m venv .venv
source .venv/bin/activate
Expand Down
2 changes: 1 addition & 1 deletion docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pip install pygpla
### From source

```bash
git clone https://github.com/CMC-lab/PyGPLA.git
git clone https://github.com/CMC-unit/PyGPLA.git
cd PyGPLA
pip install -e .
```
Expand Down
7 changes: 7 additions & 0 deletions paper/package_organization_revised.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Package organization

PyGPLA follows a function-oriented, layered design that mirrors the GPLA workflow, from preparation of the input data to statistical assessment. The main entry point is the high-level `pygpla.api.gpla` function, which coordinates preprocessing, coupling estimation, singular-value decomposition, and optional significance testing in one call. This keeps the default workflow compact while preserving access to lower-level components for advanced analyses, methodological modifications, and extensions.

Core numerical routines are separated by responsibility. The `pygpla.preprocessing` module handles trial concatenation, temporal and unit selection, spike-count filtering, optional LFP normalization, and the invocation of optional whitening. The `pygpla.core` package implements whitening, coupling-matrix construction, and singular-value decomposition, including post-processing operations such as phase alignment, spike-vector normalization, and unwhitening-aware handling of LFP vectors. Statistical procedures are collected in `pygpla.stats`, which provides surrogate-based testing using multiple spike-jittering schemes [e.g., @grun2009data] and an analytical test based on the Marchenko--Pastur random-matrix-theory threshold [@safaviUnivariateMultivariateCoupling2021].

To support reproducibility and method validation, PyGPLA includes dedicated simulation utilities in `pygpla.simulations`. These include homogeneous and inhomogeneous Poisson generators, phase-locked spike simulations, and a transient-coupling simulator that generates paired spike and LFP signals. The repository additionally provides a figure-reproduction and visualization script and an automated test suite for validating individual numerical components and end-to-end behavior. Finally, the configuration dataclasses in `pygpla.config` provide structured parameter containers for preprocessing, whitening, and statistical testing.
30 changes: 30 additions & 0 deletions paper/package_organization_revised.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
\subsection{Package organization}

PyGPLA follows a function-oriented, layered design that mirrors the GPLA workflow,
from preparation of the input data to statistical assessment. The main entry point is
the high-level \texttt{pygpla.api.gpla} function, which coordinates preprocessing,
coupling estimation, singular-value decomposition, and optional significance testing
in one call. This keeps the default workflow compact while preserving access to
lower-level components for advanced analyses, methodological modifications, and
extensions.

Core numerical routines are separated by responsibility. The
\texttt{pygpla.preprocessing} module handles trial concatenation, temporal and unit
selection, spike-count filtering, optional LFP normalization, and the invocation of
optional whitening. The \texttt{pygpla.core} package implements whitening,
coupling-matrix construction, and singular-value decomposition, including
post-processing operations such as phase alignment, spike-vector normalization, and
unwhitening-aware handling of LFP vectors. Statistical procedures are collected in
\texttt{pygpla.stats}, which provides surrogate-based testing using multiple
spike-jittering schemes \citep[e.g., multiple jittering schemes; also, see][]{grun2009data}
and an analytical test based on the Marchenko--Pastur random matrix theory threshold
\citep{safaviUnivariateMultivariateCoupling2021}.

To support reproducibility and method validation, PyGPLA includes dedicated simulation
utilities in \texttt{pygpla.simulations}. These include homogeneous and inhomogeneous
Poisson generators, phase-locked spike simulations, and a transient-coupling simulator
that generates paired spike and LFP signals. The repository additionally provides a
figure-reproduction and visualization script and an automated test suite for validating
individual numerical components and end-to-end behavior. Finally, the configuration
dataclasses in \texttt{pygpla.config} provide structured parameter containers for
preprocessing, whitening, and statistical testing.
25 changes: 15 additions & 10 deletions paper/paper.bib
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
@article{safavi2021univariate,
title={From univariate to multivariate coupling between continuous signals and point processes: a mathematical framework},
author={Safavi, Shervin and Logothetis, Nikos K and Besserve, Michel},
journal={Neural computation},
volume={33},
number={7},
pages={1751--1817},
year={2021},
publisher={MIT Press One Rogers Street, Cambridge, MA 02142-1209, USA journals-info~…}
title = {From univariate to multivariate coupling between continuous signals and point processes: A mathematical framework},
author = {Safavi, Shervin and Logothetis, Nikos K. and Besserve, Michel},
journal = {Neural Computation},
year = {2021},
volume = {33},
number = {7},
pages = {1751--1817},
doi = {10.1162/neco_a_01389}
}

@article{buzsaki2012origin,
Expand Down Expand Up @@ -201,9 +201,14 @@ @article{Nouri2025

@book{anderson2010random,
title = {An Introduction to Random Matrices},
author = {Anderson, G. W. and Guionnet, A. and Zeitouni, O.},
author = {Anderson, Greg W. and Guionnet, Alice and Zeitouni, Ofer},
publisher = {Cambridge University Press},
year = {2010}
year = {2010},
series = {Cambridge Studies in Advanced Mathematics},
volume = {118},
pages = {xiv+492},
isbn = {978-0-521-19452-5},
doi = {10.1017/CBO9780511801334}
}

@article{chavez2006proper,
Expand Down
49 changes: 37 additions & 12 deletions paper/paper.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ authors:
- name: Shervin Safavi
orcid: 0000-0002-2868-530X
corresponding: true
affiliation: "2, 3"
affiliation: "5, 6"
affiliations:
- name: Donders Institute for Brain, Cognition, and Behaviour, Radboud University, Nijmegen, Netherlands
index: 1
Expand All @@ -34,9 +34,9 @@ affiliations:
index: 6
ror: "026nmvv73"

date: "2026-03-22"
date: "22 March 2026"
bibliography: paper.bib
repository: "https://github.com/CMC-lab/PyGPLA"
repository: "https://github.com/CMC-unit/PyGPLA"
crossref: true
url: "https://pygpla.readthedocs.io/en/latest/"

Expand All @@ -46,7 +46,6 @@ url: "https://pygpla.readthedocs.io/en/latest/"

PyGPLA is a Python implementation of Generalized Phase Locking Analysis (GPLA) for multivariate analysis of coupling between spikes and local field potentials (LFPs) [@safavi2023uncovering]. For a given frequency, GPLA constructs a complex coupling matrix $\hat{C}(f) \in \mathbb{C}^{N_c \times N_u}$ between LFP channels ($N_c$) and spike units ($N_u$), then applies singular value decomposition (SVD) to reduce the dimensionality of data. The leading singular value summarizes population-level coupling strength, while the corresponding singular vectors describe dominant LFP and spike coupling modes. PyGPLA accepts a user-provided frequency-specific analytic LFP signal or phase representation and provides data selection, optional whitening and normalization, coupling-matrix construction, SVD-based decomposition, and statistical significance testing [@safavi2021univariate].


## Statement of need

Neural recordings are becoming increasingly high-dimensional and multimodal, demanding more sophisticated analysis tools. Simultaneous analysis of spiking activity and LFPs is among the most informative multi-modal approaches in systems neuroscience, providing insight into the multi-scale mechanisms underlying cognitive functions such as attention and memory [@buzsaki2012origin; @einevoll2013modelling; @herreras2016local]. LFP oscillatory activity partly reflects subthreshold processes shared by neuronal ensembles, and the synchronization between this activity and spiking is hypothesized to coordinate neural populations during cognitive processes [@buzsaki2012origin; @hagen2016hybrid].
Expand Down Expand Up @@ -86,17 +85,43 @@ We illustrate PyGPLA on synthetic transient-coupling simulations generated with

Code snippets and detailed instructions for reproducing these results are available in the package documentation and example scripts in the repository.

## Implementation details
## Software design

PyGPLA uses a function-oriented, layered design that separates the main stages of the analysis while providing a unified high-level workflow. The high-level `gpla()` function coordinates data preparation, GPLA decomposition, and optional statistical testing, returning the results and relevant bookkeeping in a single `GPLAResult` object. The underlying operations—coupling-matrix construction, SVD factorization, whitening, jitter generation, and simulation—remain independently accessible. This design provides a concise default workflow while allowing researchers to inspect, test, or replace individual methodological stages. Automated tests validate these independently accessible numerical components.

PyGPLA accepts standard NumPy arrays rather than requiring a package-specific data container, facilitating integration with existing electrophysiology workflows. Frequency selection and conversion of raw LFP voltage to an analytic signal are intentionally left upstream because these operations require experiment-specific filtering choices. PyGPLA therefore operates on a frequency-specific complex analytic signal or phase representation and warns when real-valued input is supplied.

Several numerical and interface conventions preserve continuity with the original MATLAB implementation, facilitating validation against the reference implementation and migration of existing GPLA analyses. These include its normalization alternatives, phase convention, reduced-rank whitening methods, and selected legacy parameter names. Optional PCA-based whitening reduces correlations among LFP channels, while an unwhitening operator maps the resulting coupling modes back to the original channel coordinates. Statistical inference is separated from the deterministic decomposition, allowing users to choose between a computationally inexpensive analytical RMT-based decision and more expensive spike-jitter surrogate tests. The core package depends only on NumPy; SciPy is provided as an optional dependency for documented simulation and signal-processing workflows.

## Research impact statement

The GPLA methodology has been evaluated in published simulations, biophysical network models, and multielectrode recordings, where it revealed population-level spike–field coupling patterns related to properties of the underlying neural circuits [@safavi2023uncovering]. PyGPLA transfers this established methodology from MATLAB research code into an installable, open-source Python package. The reproducible simulation included with this paper applies PyGPLA to four coupling models and demonstrates recovery of their population-level coupling structure. To our knowledge, PyGPLA is the first Python implementation that jointly decomposes the complete spike–field coupling matrix. Its immediate research contribution is therefore to make population-level GPLA available within Python-based electrophysiology workflows. Because PyGPLA is newly released, broader external adoption and independent applications remain to be established.

## AI usage disclosure

The `pygpla` package is distributed under the BSD-2-Clause license. PyGPLA follows a layered architecture separating preprocessing (`pygpla.preprocessing`), core computation (`pygpla.core`), statistical testing (`pygpla.stats`), simulation utilities (`pygpla.simulations`), and configuration (`pygpla.config`). The high-level API (`pygpla.api.gpla`) orchestrates the full pipeline in a single call, keeping default usage compact while preserving access to lower-level components for advanced analyses. The package is built on NumPy [@harris2020array] and SciPy [@virtanen2020fundamental], and includes a `pytest` test suite with continuous integration via GitHub Actions.
Over the course of PyGPLA’s development, the authors used OpenAI GPT-family
models through ChatGPT and OpenAI Codex, including models from the GPT-5
family. This assistance occurred over an extended period during which the
available models were updated; consequently, exact model snapshots and version
identifiers were not recorded for every interaction.

## Use of generative AI
The models were used to assist with porting selected MATLAB scripts to Python,
refactoring code, drafting and restructuring documentation, and conducting
language editing and grammatical review of the manuscript. AI-generated outputs
were treated as preliminary suggestions rather than authoritative
implementations.

Generative AI tools were used only to assist with drafting documentation and
refactoring code for style. All AI-assisted output was reviewed, tested, and
validated by the authors, who take full responsibility for the correctness of the
software and the content of this paper. The scientific method, algorithmic design,
and numerical implementation of GPLA were carried out by the authors.
All AI-assisted code and text were reviewed and edited by the authors.
Translated code was reviewed against the original MATLAB implementation and
the published mathematical description of GPLA. Its behavior was evaluated
through tests, reproducible simulations, and manual inspection. As an
additional human-led validation step, the authors reproduced Figure 2 from the
original GPLA publication using PyGPLA and compared the resulting coupling
patterns with the published results, providing a further check of the ported
implementation. The authors made the scientific, architectural, and
methodological decisions and take full responsibility for the accuracy,
originality, licensing, and integrity of the software, documentation, and
paper.

## Acknowledgments

Expand Down
Binary file modified paper/paper.pdf
Binary file not shown.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ figures = [
]

[project.urls]
Repository = "https://github.com/CMC-lab/PyGPLA"
Documentation = "https://github.com/CMC-lab/PyGPLA#readme"
Repository = "https://github.com/CMC-unit/PyGPLA"
Documentation = "https://github.com/CMC-unit/PyGPLA#readme"

[tool.hatch.version]
path = "src/pygpla/_version.py"
Expand Down
Loading