Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
61 changes: 61 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# ...
# Copyright 2021 Brooks M. Musangu and Jan Drugowitsch.
# license Modified BSD, see LICENSE.txt for details.
# ...
name: CI Tests and Docs

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
test:
name: Run Pytest Suite
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 package and test dependencies
run: |
python -m pip install --upgrade pip
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 Pandoc
run: |
sudo apt-get update
sudo apt-get install -y pandoc

- 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
17 changes: 17 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
@@ -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
50 changes: 32 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
# 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)
[![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.
Expand All @@ -36,41 +45,46 @@ 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/workflows/tests.yml) on every push and pull request.

## License
Modified BSD License based on Elephant, see [LICENSE.txt](LICENSE.txt) for details.


## Copyright

:copyright: 2021 Brooks M. Musangu and Jan Drugowitsch
:copyright: 2021-2025 Brooks M. Musangu and Jan Drugowitsch

## Acknowledgments

Expand Down
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions docs/requirements.txt

This file was deleted.

1 change: 0 additions & 1 deletion gpfa/gpfa.py
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
35 changes: 35 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -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 = {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"
4 changes: 0 additions & 4 deletions requirements.txt

This file was deleted.

File renamed without changes.
File renamed without changes.