From b30b776b5efd8ed069b1f24f8c3b1486b27fd2a2 Mon Sep 17 00:00:00 2001 From: bmusangu Date: Fri, 9 May 2025 13:31:34 -0400 Subject: [PATCH 1/9] Rename test files to match pytest naming conventions --- requirements.txt | 1 + test/{gpfa.py => test_gpfa.py} | 0 test/{preprocessing.py => test_preprocessing.py} | 0 3 files changed, 1 insertion(+) rename test/{gpfa.py => test_gpfa.py} (100%) rename test/{preprocessing.py => test_preprocessing.py} (100%) diff --git a/requirements.txt b/requirements.txt index 1b1d446..8f0f856 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ numpy==2.2.1 +pytest==7.3.1 scikit-learn==1.6.0 scipy==1.15.0 tqdm==4.67.1 diff --git a/test/gpfa.py b/test/test_gpfa.py similarity index 100% rename from test/gpfa.py rename to test/test_gpfa.py diff --git a/test/preprocessing.py b/test/test_preprocessing.py similarity index 100% rename from test/preprocessing.py rename to test/test_preprocessing.py From f9a4857b3375350e4214bbf80e6bce576b3548fe Mon Sep 17 00:00:00 2001 From: bmusangu Date: Fri, 9 May 2025 13:53:51 -0400 Subject: [PATCH 2/9] Add GitHub Actions workflow for automated pytest testing --- .github/workflows/tests.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..e69de29 From e24d73ff02f947d9b36749494f0435e3ed829f7c Mon Sep 17 00:00:00 2001 From: bmusangu Date: Fri, 9 May 2025 14:44:45 -0400 Subject: [PATCH 3/9] Add CI badge to README And GitHub Actions workflow for automated pytest testing --- .github/workflows/tests.yml | 29 +++++++++++++++++++++++++++++ README.md | 4 +++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e69de29..f91bf41 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -0,0 +1,29 @@ +name: Automated Tests + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.x + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest + pip install -e . + + - name: Run tests + run: | + pytest test/ diff --git a/README.md b/README.md index 18cf359..9c5f399 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# GPFA_for_sklearn +# BlockInvGPFA + +[![Automated Tests](https://github.com/CausalityInMotion/BlockInverseGPFA/actions/workflows/tests.yml/badge.svg)](https://github.com/CausalityInMotion/BlockInverseGPFA/actions/workflows/tests.yml) This package is an implementation of Gaussian Process Factor Analysis (GPFA) by Byron Yu et al., (2009) in python. The code is based on [Elephant](https://elephant.readthedocs.io/en/latest/reference/gpfa.html)'s From 3f1a5a57d4eb18c6f3af24d3c2663a257cd782de Mon Sep 17 00:00:00 2001 From: bmusangu Date: Fri, 9 May 2025 15:07:52 -0400 Subject: [PATCH 4/9] Update copyright headers in workflow and GPFA file --- .github/workflows/tests.yml | 4 ++++ gpfa/gpfa.py | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f91bf41..29b5484 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,3 +1,7 @@ +# ... +# Copyright 2021 Brooks M. Musangu and Jan Drugowitsch. +# license Modified BSD, see LICENSE.txt for details. +# ... name: Automated Tests on: diff --git a/gpfa/gpfa.py b/gpfa/gpfa.py index 0aad726..2d1b544 100644 --- a/gpfa/gpfa.py +++ b/gpfa/gpfa.py @@ -1,5 +1,4 @@ # ... -# Moving this here to prevent from showing up on sphinx pages # Copyright 2021 Brooks M. Musangu and Jan Drugowitsch. # Copyright 2014-2020 by the Elephant team. # Modified BSD, see LICENSE.txt for details. From 786a218205a184e946632f890286d3c5978e24b3 Mon Sep 17 00:00:00 2001 From: bmusangu Date: Fri, 9 May 2025 16:45:43 -0400 Subject: [PATCH 5/9] Refactor project dependencies: migrate requirements to pyproject.toml and remove old requirements files. --- docs/requirements.txt | 4 ---- pyproject.toml | 35 +++++++++++++++++++++++++++++++++++ requirements.txt | 5 ----- 3 files changed, 35 insertions(+), 9 deletions(-) delete mode 100644 docs/requirements.txt create mode 100644 pyproject.toml delete mode 100644 requirements.txt diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 11b160f..0000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -nbsphinx==0.9.6 -numpydoc==1.8.0 -Sphinx==8.1.3 -sphinx-rtd-theme==3.0.2 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e7520c1 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,35 @@ +[build-system] +requires = ["setuptools>=42", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "blockinversegpfa" +version = "0.1.0" +description = "A scikit-learn-compatible GPFA implementation using block matrix inversion." +authors = [ + {name = "Brooks M. MUSANGU", email = "brooks_musangu@hms.harvard.edu"}, + {name = "Jan DRUGOWITSCH", email = "jan_drugowitsch@hms.harvard.edu"} +] +license = {text = "BSD-3-Clause", file = "LICENSE.txt"} +readme = "README.md" +requires-python = ">=3.9" +dependencies = [ + "numpy==2.2.1", + "scikit-learn==1.6.0", + "scipy==1.15.0", + "tqdm==4.67.1" +] + +[project.optional-dependencies] +test = [ + "pytest==7.3.1" +] +docs = [ + "nbsphinx==0.9.6", + "numpydoc==1.8.0", + "Sphinx==8.1.3", + "sphinx-rtd-theme==3.0.2" +] + +[project.urls] +Homepage = "https://github.com/CausalityInMotion/BlockInverseGPFA" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 8f0f856..0000000 --- a/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -numpy==2.2.1 -pytest==7.3.1 -scikit-learn==1.6.0 -scipy==1.15.0 -tqdm==4.67.1 From 94b08277df759919127525ee049b02d05408a308 Mon Sep 17 00:00:00 2001 From: bmusangu Date: Fri, 9 May 2025 16:46:04 -0400 Subject: [PATCH 6/9] Update GitHub Actions workflow for CI tests and documentation build --- .github/workflows/tests.yml | 37 ++++++++++++++++++++++++++++++------- docs/conf.py | 3 ++- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 29b5484..f7623b3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,7 +2,7 @@ # Copyright 2021 Brooks M. Musangu and Jan Drugowitsch. # license Modified BSD, see LICENSE.txt for details. # ... -name: Automated Tests +name: CI Tests and Docs on: push: @@ -11,23 +11,46 @@ on: branches: [ main ] jobs: - build: + test: + name: Run Pytest Suite runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - - name: Set up Python 3.x + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.x' - - name: Install dependencies + - name: Install package and test dependencies run: | python -m pip install --upgrade pip - pip install pytest - pip install -e . + pip install .[test] - name: Run tests run: | pytest test/ + + docs: + name: Build Documentation + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install docs dependencies + run: | + python -m pip install --upgrade pip + pip install .[docs] + + - name: Build Sphinx documentation + run: | + sphinx-build -b html docs docs/_build diff --git a/docs/conf.py b/docs/conf.py index 32b3f22..0d7c7b6 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,8 @@ authors = 'Brooks M. Musangu and Jan Drugowitsch' copyright = "2021-{this_year}, {authors}".format( this_year=date.today().year, authors=authors) -release = '0.0.1' +release = '0.1.0.' +version = '0.1.0' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration From ab61a9de99fedb1a76e1bce9f3022db84b476e65 Mon Sep 17 00:00:00 2001 From: bmusangu Date: Fri, 9 May 2025 18:17:31 -0400 Subject: [PATCH 7/9] Add Read the Docs configuration and update README for documentation setup --- .readthedocs.yml | 17 +++++++++++++++++ README.md | 46 +++++++++++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 .readthedocs.yml diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..4304ba8 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,17 @@ +# .readthedocs.yml +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.13" + +python: + install: + - method: pip + path: . + extra_requirements: + - docs + +sphinx: + configuration: docs/conf.py diff --git a/README.md b/README.md index 9c5f399..e04bc87 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,35 @@ # BlockInvGPFA [![Automated Tests](https://github.com/CausalityInMotion/BlockInverseGPFA/actions/workflows/tests.yml/badge.svg)](https://github.com/CausalityInMotion/BlockInverseGPFA/actions/workflows/tests.yml) +[![Documentation Status](https://readthedocs.org/projects/blockinversegpfa/badge/?version=latest)](https://blockinversegpfa.readthedocs.io/en/latest/) + +This package provides a Python implementation of **Gaussian Process Factor Analysis (GPFA)** that incorporates a novel approach to efficiently handle variable-length time series data. Building on the original method by [Byron Yu et al. (2009)](https://papers.nips.cc/paper/2009/hash/6c1b887a379c4f0c2c621f305d15f6b0-Abstract.html), this implementation introduces a **block-matrix–based inversion strategy** that reuses kernel computations across trials of different lengths. + +The package also includes **scikit-learn–compatible API** for integration into existing ML workflows such as: +- A **Modular Preprocessing** — Separates data preprocessing from model logic via a dedicated `EventTimesToCounts` transformer. + - Accepts standard array-like inputs (not `Neo` objects), simplifying integration with other tools. + - Follows scikit-learn's transformer–estimator interface for clean, reusable workflows. +- A new **variance-explained metric** to evaluate GPFA model fits. + +This implementation is adapted from [Elephant](https://elephant.readthedocs.io/en/latest/reference/gpfa.html)’s GPFA codebase with substantial modifications to improve performance, modularity, and usability in Python-based pipelines. -This package is an implementation of Gaussian Process Factor Analysis (GPFA) by Byron Yu et al., -(2009) in python. The code is based on [Elephant](https://elephant.readthedocs.io/en/latest/reference/gpfa.html)'s -python implementation plus additional modules and functional implementations. ## Usage ### Installation ----------------- -- Clone the project locally using +Install directly from GitHub using `pip`: ```bash -$ git clone https://github.com/CausalityInMotion/GPFA_for_sklearn +$ pip install git+https://github.com/CausalityInMotion/BlockInverseGPFA.git ``` - -Ensure you are in the working directory of the project. - -Then install the project's required packages uisng +Or clone the repo and install locally: ```bash -$ pip install -r requirements.txt +$ git clone https://github.com/CausalityInMotion/BlockInverseGPFA.git +$ cd BlockInverseGPFA +$ pip install . # or pip install .[test,docs] to include optional dependencies ``` You are now set to use the package. @@ -38,33 +45,38 @@ Building the documentation requires the following packages: - [numpydoc](https://numpydoc.readthedocs.io/) - [Jupyter Notebook Tools for Sphinx](https://nbsphinx.readthedocs.io/) -You can install the required packages either using the `docs/requirements.txt` file, +You can install the required documentation dependencies by: ```bash -$ pip install -r docs/requirements.txt +$ pip install .[docs] ``` or manually by calling ```bash $ pip install sphinx sphinx-rtd-theme numpydoc nbsphinx ``` -Finally, to view the documentation, run +Finally, to view the documentation locally, run ```bash $ cd docs $ make html $ open _build/html/index.html ``` +or view them online: +[BlockInvGPFA docs](https://blockinversegpfa.readthedocs.io/en/latest/) + +A detailed walkthrough of the package — including how to fit the model to real neural data — is available in the Jupyter notebook example: (link) ----------- ### Tests ----------- -To run the unittests in the [test](test) folder, use the following command in your command line/terminal: +To run the full test suite in the [test](test) folder, use: ```bash -$ python -m unittest test.gpfa -$ python -m unittest test.preprocessing +$ pip install .[test] +$ pytest test/ ``` +Tests are automatically run via [GitHub Actions](https://github.com/CausalityInMotion/BlockInverseGPFA/actions/new) on every push and pull request. ## License Modified BSD License based on Elephant, see [LICENSE.txt](LICENSE.txt) for details. @@ -72,7 +84,7 @@ Modified BSD License based on Elephant, see [LICENSE.txt](LICENSE.txt) for detai ## Copyright -:copyright: 2021 Brooks M. Musangu and Jan Drugowitsch +:copyright: 2021-2025 Brooks M. Musangu and Jan Drugowitsch ## Acknowledgments From a97440fc589507d74ca3f9d0f801162b4d89352f Mon Sep 17 00:00:00 2001 From: bmusangu Date: Fri, 9 May 2025 20:08:06 -0400 Subject: [PATCH 8/9] Fix GitHub Actions link in README and update license format in pyproject.toml --- README.md | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e04bc87..b5b285d 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ To run the full test suite in the [test](test) folder, use: $ pip install .[test] $ pytest test/ ``` -Tests are automatically run via [GitHub Actions](https://github.com/CausalityInMotion/BlockInverseGPFA/actions/new) on every push and pull request. +Tests are automatically run via [GitHub Actions](https://github.com/CausalityInMotion/BlockInverseGPFA/actions/workflows/tests.yml) on every push and pull request. ## License Modified BSD License based on Elephant, see [LICENSE.txt](LICENSE.txt) for details. diff --git a/pyproject.toml b/pyproject.toml index e7520c1..2fb27b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ authors = [ {name = "Brooks M. MUSANGU", email = "brooks_musangu@hms.harvard.edu"}, {name = "Jan DRUGOWITSCH", email = "jan_drugowitsch@hms.harvard.edu"} ] -license = {text = "BSD-3-Clause", file = "LICENSE.txt"} +license = {file = "LICENSE.txt"} readme = "README.md" requires-python = ">=3.9" dependencies = [ From 78403f1b1cc341563b8fa2fd471c26713742cb7b Mon Sep 17 00:00:00 2001 From: bmusangu Date: Fri, 9 May 2025 20:40:37 -0400 Subject: [PATCH 9/9] Add Pandoc installation step to CI workflow for documentation build: required to convert notebook markdown cells into reStructuredText or HTML --- .github/workflows/tests.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f7623b3..b9f295a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -46,6 +46,11 @@ jobs: with: python-version: '3.x' + - name: Install Pandoc + run: | + sudo apt-get update + sudo apt-get install -y pandoc + - name: Install docs dependencies run: | python -m pip install --upgrade pip