Metadata-Version: 2.1
Name: pycorre
Version: 0.1.0
Summary: Torch implementation of the NoRMCorre motion correction algorithm.
Home-page: https://github.com/ryanirl/pycorre
License: MIT
Author: Ryan Peters
Author-email: RyanIRL@icloud.com
Requires-Python: >=3.9,<4.0
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Dist: numpy
Requires-Dist: torch
Requires-Dist: tqdm
Project-URL: Repository, https://github.com/ryanirl/pycorre
Description-Content-Type: text/markdown

<p align="center">
 <img src="./imgs/logo.png" width="45%">
</p>

# PyCorre

Fast, GPU-accelerated rigid and piecewise-rigid motion correction for
calcium-imaging recordings. PyCorre implements the
[NoRMCorre](https://www.sciencedirect.com/science/article/pii/S0165027017302753)
algorithm, which is the same phase-correlation + upsampled-DFT method used by
[CaImAn](https://github.com/flatironinstitute/CaImAn), but rewritten in
[PyTorch](https://pytorch.org/). The whole stack is corrected in batched
operations that run on CPU or GPU from a single, dependency-light codebase.


## Installation

```
pip install pycorre
```

The only runtime dependencies are `torch`, `numpy`, and `tqdm`. GPU support is
whatever your PyTorch build provides (install the appropriate CUDA wheel of
torch for your machine).


## Quickstart

```python
import numpy as np
from pycorre import RigidMotionCorrection, PWRigidMotionCorrection

# A recording of shape (n_frames, height, width); numpy array or torch tensor.
frames = ...

# Rigid correction on the GPU.
model = RigidMotionCorrection(device="cuda")  # or "cpu" / "auto"
corrected = model.fit_transform(frames)

# Piecewise-rigid (non-rigid) correction.
model = PWRigidMotionCorrection(device="cuda", strides=(96, 96), overlaps=(32, 32))
corrected = model.fit_transform(frames)
```

The API follows scikit-learn's `fit` / `transform` / `fit_transform` pattern.
`fit` estimates the template (unless you pass one) and finds the per-frame
shifts; `transform` applies them. Inputs may be numpy arrays or torch tensors;
numpy in and numpy out.


## Performance

The table below shows the rigid correction throughput on a real recording with 
resolution 360x640 for 1800 frames. 

| method | device | fps | vs PyCorre (GPU) |
|---|---|---|---|
| **PyCorre (torch)** | **GPU** | **~2,285** | **1.0x** |
| [jnormcorre](https://github.com/apasarkar/jnormcorre) (NoRMCorre in JAX) | GPU | ~762 | 3.0x slower |
| **PyCorre (torch)** | **CPU** | **~468** | 4.9x slower |
| jnormcorre | CPU | ~162 | 14x slower |
| CaImAn reference | CPU | ~103 | 22x slower |

On this sample, PyCorre is ~**22x faster than CaImAn** and ~**3x faster than jnormcorre**.
On CPU alone, with no GPU at all, PyCorre still leads, running ~**4.5x faster than the
CaImAn reference** and ~**2.9x faster than jnormcorre**.

The scaling curve can be seen here:

<p align="center">
 <img src="./imgs/pycorre-scaling.png" width="100%">
</p>


## Author

PyCorre is written and maintained by **Ryan 'RyanIRL' Peters** ([@ryanirl](https://github.com/ryanirl)).


## Citation

If you use PyCorre in your research, please cite it:

```bibtex
@software{peters_pycorre,
  author = {Peters, Ryan},
  title  = {{PyCorre}: GPU-accelerated rigid and piecewise-rigid motion correction for calcium imaging},
  url    = {https://github.com/ryanirl/pycorre},
  year   = {2026}
}
```

PyCorre implements the NoRMCorre algorithm; if you use it, please also cite the
original method:

> Pnevmatikakis, E. A., & Giovannucci, A. (2017). NoRMCorre: An online algorithm
> for piecewise rigid motion correction of calcium imaging data. *Journal of
> Neuroscience Methods*, 291, 83-94. https://doi.org/10.1016/j.jneumeth.2017.07.031


## License

`pycorre` is released under the **MIT License** (see [LICENSE](./LICENSE)). 
