diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..c2c2146 --- /dev/null +++ b/.readthedocs.yaml @@ -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 diff --git a/README.md b/README.md index 49af894..df9eb1c 100644 --- a/README.md +++ b/README.md @@ -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 . ``` diff --git a/docs/contributing.md b/docs/contributing.md index a8a47b2..92671ee 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -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 diff --git a/docs/installation.md b/docs/installation.md index 408ce16..ec6df78 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -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 . ``` diff --git a/paper/package_organization_revised.md b/paper/package_organization_revised.md new file mode 100644 index 0000000..ea3846f --- /dev/null +++ b/paper/package_organization_revised.md @@ -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. diff --git a/paper/package_organization_revised.tex b/paper/package_organization_revised.tex new file mode 100644 index 0000000..ac15ef7 --- /dev/null +++ b/paper/package_organization_revised.tex @@ -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. diff --git a/paper/paper.bib b/paper/paper.bib index 0de0423..a391c59 100644 --- a/paper/paper.bib +++ b/paper/paper.bib @@ -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, @@ -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, diff --git a/paper/paper.md b/paper/paper.md index 1cf058b..459cf0d 100644 --- a/paper/paper.md +++ b/paper/paper.md @@ -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 @@ -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/" @@ -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]. @@ -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 diff --git a/paper/paper.pdf b/paper/paper.pdf index dfcc47c..5ce6fee 100644 Binary files a/paper/paper.pdf and b/paper/paper.pdf differ diff --git a/pyproject.toml b/pyproject.toml index ddbaf37..c835dab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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"