Metadata-Version: 2.4
Name: roicat
Version: 1.5.2
Summary: A library for classifying and tracking ROIs.
Home-page: https://github.com/RichieHakim/ROICaT
Author: Richard Hakim
License: LICENSE
Keywords: neuroscience,neuroimaging,machine learning,deep learning
Requires-Python: >=3.10, <3.14
Description-Content-Type: text/markdown
License-File: LICENSE.md
Provides-Extra: all
Requires-Dist: hdbscan==0.8.40; extra == "all"
Requires-Dist: holoviews[recommended]==1.21.0; extra == "all"
Requires-Dist: jupyter==1.0.0; extra == "all"
Requires-Dist: kymatio==0.3.0; extra == "all"
Requires-Dist: matplotlib==3.10.3; extra == "all"
Requires-Dist: natsort==8.4.0; extra == "all"
Requires-Dist: numpy==2.2.6; extra == "all"
Requires-Dist: opencv_contrib_python_headless<=4.12.0.88; extra == "all"
Requires-Dist: optuna==4.3.0; extra == "all"
Requires-Dist: Pillow==11.3.0; extra == "all"
Requires-Dist: pytest==8.4.1; extra == "all"
Requires-Dist: scikit_learn==1.7.1; extra == "all"
Requires-Dist: scipy==1.15.3; extra == "all"
Requires-Dist: seaborn==0.13.2; extra == "all"
Requires-Dist: sparse==0.17.0; extra == "all"
Requires-Dist: tqdm==4.67.1; extra == "all"
Requires-Dist: umap_learn==0.5.9.post2; extra == "all"
Requires-Dist: xxhash==3.5.0; extra == "all"
Requires-Dist: bokeh==3.7.3; extra == "all"
Requires-Dist: psutil==7.0.0; extra == "all"
Requires-Dist: py_cpuinfo==9.0.0; extra == "all"
Requires-Dist: PyYAML==6.0.2; extra == "all"
Requires-Dist: mat73==0.65; extra == "all"
Requires-Dist: torch==2.7.1; extra == "all"
Requires-Dist: torchvision==0.22.1; extra == "all"
Requires-Dist: torchaudio==2.7.1; extra == "all"
Requires-Dist: selenium==4.34.2; extra == "all"
Requires-Dist: skl2onnx==1.19.1; extra == "all"
Requires-Dist: onnx==1.17.0; extra == "all"
Requires-Dist: onnxruntime==1.22.1; extra == "all"
Requires-Dist: jupyter_bokeh==4.0.5; extra == "all"
Requires-Dist: onnx2torch==1.5.15; extra == "all"
Requires-Dist: scikit-image==0.25.2; extra == "all"
Requires-Dist: richfile>=0.4.5; extra == "all"
Requires-Dist: romatch-roicat>=0.1.1; extra == "all"
Requires-Dist: kornia==0.8.1; extra == "all"
Provides-Extra: all-latest
Requires-Dist: hdbscan; extra == "all-latest"
Requires-Dist: holoviews[recommended]; extra == "all-latest"
Requires-Dist: jupyter; extra == "all-latest"
Requires-Dist: kymatio; extra == "all-latest"
Requires-Dist: matplotlib; extra == "all-latest"
Requires-Dist: natsort; extra == "all-latest"
Requires-Dist: numpy; extra == "all-latest"
Requires-Dist: opencv_contrib_python_headless; extra == "all-latest"
Requires-Dist: optuna; extra == "all-latest"
Requires-Dist: Pillow; extra == "all-latest"
Requires-Dist: pytest; extra == "all-latest"
Requires-Dist: scikit_learn; extra == "all-latest"
Requires-Dist: scipy; extra == "all-latest"
Requires-Dist: seaborn; extra == "all-latest"
Requires-Dist: sparse; extra == "all-latest"
Requires-Dist: tqdm; extra == "all-latest"
Requires-Dist: umap_learn; extra == "all-latest"
Requires-Dist: xxhash; extra == "all-latest"
Requires-Dist: bokeh; extra == "all-latest"
Requires-Dist: psutil; extra == "all-latest"
Requires-Dist: py_cpuinfo; extra == "all-latest"
Requires-Dist: PyYAML; extra == "all-latest"
Requires-Dist: mat73; extra == "all-latest"
Requires-Dist: torch; extra == "all-latest"
Requires-Dist: torchvision; extra == "all-latest"
Requires-Dist: torchaudio; extra == "all-latest"
Requires-Dist: selenium; extra == "all-latest"
Requires-Dist: skl2onnx; extra == "all-latest"
Requires-Dist: onnx; extra == "all-latest"
Requires-Dist: onnxruntime; extra == "all-latest"
Requires-Dist: jupyter_bokeh; extra == "all-latest"
Requires-Dist: onnx2torch; extra == "all-latest"
Requires-Dist: scikit-image; extra == "all-latest"
Requires-Dist: richfile; extra == "all-latest"
Requires-Dist: romatch-roicat; extra == "all-latest"
Requires-Dist: kornia; extra == "all-latest"
Provides-Extra: core
Requires-Dist: jupyter==1.0.0; extra == "core"
Requires-Dist: matplotlib==3.10.3; extra == "core"
Requires-Dist: mat73==0.65; extra == "core"
Requires-Dist: natsort==8.4.0; extra == "core"
Requires-Dist: numpy==2.2.6; extra == "core"
Requires-Dist: optuna==4.3.0; extra == "core"
Requires-Dist: Pillow==11.3.0; extra == "core"
Requires-Dist: pytest==8.4.1; extra == "core"
Requires-Dist: PyYAML==6.0.2; extra == "core"
Requires-Dist: scikit_learn==1.7.1; extra == "core"
Requires-Dist: scipy==1.15.3; extra == "core"
Requires-Dist: seaborn==0.13.2; extra == "core"
Requires-Dist: sparse==0.17.0; extra == "core"
Requires-Dist: tqdm==4.67.1; extra == "core"
Requires-Dist: xxhash==3.5.0; extra == "core"
Requires-Dist: torch==2.7.1; extra == "core"
Requires-Dist: torchvision==0.22.1; extra == "core"
Requires-Dist: torchaudio==2.7.1; extra == "core"
Requires-Dist: psutil==7.0.0; extra == "core"
Requires-Dist: py_cpuinfo==9.0.0; extra == "core"
Requires-Dist: skl2onnx==1.19.1; extra == "core"
Requires-Dist: onnx==1.17.0; extra == "core"
Requires-Dist: onnxruntime==1.22.1; extra == "core"
Requires-Dist: richfile>=0.4.5; extra == "core"
Provides-Extra: classification
Requires-Dist: umap_learn==0.5.9.post2; extra == "classification"
Requires-Dist: bokeh==3.7.3; extra == "classification"
Requires-Dist: holoviews[recommended]==1.21.0; extra == "classification"
Requires-Dist: jupyter_bokeh==4.0.5; extra == "classification"
Requires-Dist: jupyter==1.0.0; extra == "classification"
Requires-Dist: matplotlib==3.10.3; extra == "classification"
Requires-Dist: mat73==0.65; extra == "classification"
Requires-Dist: natsort==8.4.0; extra == "classification"
Requires-Dist: numpy==2.2.6; extra == "classification"
Requires-Dist: optuna==4.3.0; extra == "classification"
Requires-Dist: Pillow==11.3.0; extra == "classification"
Requires-Dist: pytest==8.4.1; extra == "classification"
Requires-Dist: PyYAML==6.0.2; extra == "classification"
Requires-Dist: scikit_learn==1.7.1; extra == "classification"
Requires-Dist: scipy==1.15.3; extra == "classification"
Requires-Dist: seaborn==0.13.2; extra == "classification"
Requires-Dist: sparse==0.17.0; extra == "classification"
Requires-Dist: tqdm==4.67.1; extra == "classification"
Requires-Dist: xxhash==3.5.0; extra == "classification"
Requires-Dist: torch==2.7.1; extra == "classification"
Requires-Dist: torchvision==0.22.1; extra == "classification"
Requires-Dist: torchaudio==2.7.1; extra == "classification"
Requires-Dist: psutil==7.0.0; extra == "classification"
Requires-Dist: py_cpuinfo==9.0.0; extra == "classification"
Requires-Dist: skl2onnx==1.19.1; extra == "classification"
Requires-Dist: onnx==1.17.0; extra == "classification"
Requires-Dist: onnxruntime==1.22.1; extra == "classification"
Requires-Dist: richfile>=0.4.5; extra == "classification"
Provides-Extra: tracking
Requires-Dist: opencv_contrib_python_headless<=4.12.0.88; extra == "tracking"
Requires-Dist: hdbscan==0.8.40; extra == "tracking"
Requires-Dist: kymatio==0.3.0; extra == "tracking"
Requires-Dist: kornia==0.8.1; extra == "tracking"
Requires-Dist: romatch-roicat>=0.1.1; extra == "tracking"
Requires-Dist: jupyter==1.0.0; extra == "tracking"
Requires-Dist: matplotlib==3.10.3; extra == "tracking"
Requires-Dist: mat73==0.65; extra == "tracking"
Requires-Dist: natsort==8.4.0; extra == "tracking"
Requires-Dist: numpy==2.2.6; extra == "tracking"
Requires-Dist: optuna==4.3.0; extra == "tracking"
Requires-Dist: Pillow==11.3.0; extra == "tracking"
Requires-Dist: pytest==8.4.1; extra == "tracking"
Requires-Dist: PyYAML==6.0.2; extra == "tracking"
Requires-Dist: scikit_learn==1.7.1; extra == "tracking"
Requires-Dist: scipy==1.15.3; extra == "tracking"
Requires-Dist: seaborn==0.13.2; extra == "tracking"
Requires-Dist: sparse==0.17.0; extra == "tracking"
Requires-Dist: tqdm==4.67.1; extra == "tracking"
Requires-Dist: xxhash==3.5.0; extra == "tracking"
Requires-Dist: torch==2.7.1; extra == "tracking"
Requires-Dist: torchvision==0.22.1; extra == "tracking"
Requires-Dist: torchaudio==2.7.1; extra == "tracking"
Requires-Dist: psutil==7.0.0; extra == "tracking"
Requires-Dist: py_cpuinfo==9.0.0; extra == "tracking"
Requires-Dist: skl2onnx==1.19.1; extra == "tracking"
Requires-Dist: onnx==1.17.0; extra == "tracking"
Requires-Dist: onnxruntime==1.22.1; extra == "tracking"
Requires-Dist: richfile>=0.4.5; extra == "tracking"
Dynamic: author
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-python
Dynamic: summary

# Welcome to ROICaT

<div>
    <img src="docs/media/logo1.png" alt="ROICaT" width="200"  align="right"  style="margin-left: 20px"/>
</div>

[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/RichieHakim/ROICaT)
[![build](https://github.com/RichieHakim/ROICaT/actions/workflows/.github/workflows/build.yml/badge.svg)](https://github.com/RichieHakim/ROICaT/actions/workflows/build.yml) 
[![PyPI version](https://badge.fury.io/py/roicat.svg)](https://badge.fury.io/py/roicat)
[![Downloads](https://pepy.tech/badge/roicat)](https://pepy.tech/project/roicat)
[![build](https://github.com/RichieHakim/ROICaT/actions/workflows/.github/workflows/check_huggingface_space.yml/badge.svg)](https://github.com/RichieHakim/ROICaT/actions/workflows/check_huggingface_space.yml)


**🎉 CONTRIBUTIONS WELCOME! 🎉** \
See the [TODO](#todo) section

- **Documentation: [https://roicat.readthedocs.io/en/latest/](https://roicat.readthedocs.io/en/latest/)**. 
- Overview: [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/RichieHakim/ROICaT)
- Discussion forum: [https://groups.google.com/g/roicat_support](https://groups.google.com/g/roicat_support)
- Technical support: [Github Issues](https://github.com/RichieHakim/ROICaT/issues)

## **R**egion **O**f **I**nterest **C**lassification **a**nd **T**racking ᗢ
A simple-to-use Python package for automatically classifying images of cells and tracking them across imaging sessions/planes.
<div>
    <img src="docs/media/tracking_FOV_clusters_rich.gif" alt="tracking_FOV_clusters_rich"  width="400"  align="right" style="margin-left: 20px"/>
</div>

**Why use ROICaT?**
- **It's easy to use. You don't need to know how to code. You can use the
  interactive notebooks or online app to run the pipelines with just a few
  clicks.**
- It's accurate. ROICaT was desgined to be better than existing tools. It is
  capable of classifying and tracking neuron ROIs at accuracies approaching
  human performance out of the box.
- It's fast and computational requirements are low. You can run it on a laptop.
  It was designed to be used with >1M ROIs, and can utilize GPUs to speed things
  up.

With ROICaT, you can:
- **Classify ROIs** into different categories (e.g. neurons, dendrites, glia,
  etc.).
- **Track ROIs** across imaging sessions/planes (e.g. ROI #1 in session 1 is the
  same as ROI #7 in session 2).

**What data types can ROICaT process?** 
- ROICaT can accept any imaging data format including: Suite2p, CaImAn, CNMF,
  NWB, raw/custom ROI data and more. See below for details on how to use any
  data type with ROICaT.

<br>
<br>

# How to use ROICaT
<div>
    <img src="docs/media/umap_with_labels.png" alt="ROICaT" width="300"  align="right"  style="margin-left: 20px"/>
</div>

### TRACKING: 
- [Online App](https://huggingface.co/spaces/richiehakim/ROICaT_tracking): Good for first time users. Try it out without installing anything.
- [Interactive
  notebook](https://github.com/RichieHakim/ROICaT/blob/main/notebooks/tracking/1_tracking_interactive_notebook.ipynb) (also available in colab) $~$<a target="_blank" href="https://githubtocolab.com/RichieHakim/ROICaT/blob/main/notebooks/tracking/1_tracking_interactive_notebook.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
- [Command line interface script](https://github.com/RichieHakim/ROICaT/blob/main/scripts/run_tracking.sh): 
```shell
roicat --pipeline tracking --path_params /path/to/params.yaml --dir_data /folder/with/data/ --dir_save /folder/save/ --prefix_name_save expName --verbose
```
  
### CLASSIFICATION:
- [Interactive notebook -
  Drawing](https://github.com/RichieHakim/ROICaT/blob/main/notebooks/classification/A1_classify_by_drawingSelection.ipynb). (also available in colab) $~$<a target="_blank" href="https://githubtocolab.com/RichieHakim/ROICaT/blob/main/notebooks/classification/A1_classify_by_drawingSelection.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>: $~~$ Use mouse to draw circles around regions of a UMAP to classify ROIs.
- [Interactive notebook - Simple interactive
  Labeling](https://github.com/RichieHakim/ROICaT/blob/main/notebooks/classification/B1a_labeling_interactive.ipynb): $~~$ Images of ROIs are displayed and you use the keyboard to manually label them.
- [Interactive notebook - Interactive labeling with
  drawing](https://github.com/RichieHakim/ROICaT/blob/main/notebooks/classification/B1b_labeling_drawingAndInteractive.ipynb): $~~$ Draw circles around regions of a UMAP to subselect ROIs for manual labeling.
- [Interactive notebook - Train
  classifier](https://github.com/RichieHakim/ROICaT/blob/main/notebooks/classification/B2_classifier_train_interactive.ipynb)
- [Interactive notebook - Inference with
  classifier](https://github.com/RichieHakim/ROICaT/blob/main/notebooks/classification/B3_classifier_inference_interactive.ipynb)

**OTHER:** 
- [Custom data importing
  notebook](https://github.com/RichieHakim/ROICaT/blob/main/notebooks/other/demo_data_importing.ipynb)
- Use the API to integrate ROICaT functions into your own code:
  [Documentation](https://roicat.readthedocs.io/en/latest/roicat.html).
- Run the full tracking pipeline using the CLI or
  `roicat.pipelines.pipeline_tracking` with default parameters generated from
  `roicat.util.get_default_paramaters()` saved as a yaml file.
<!-- - Train a new ROInet model using the provided Jupyter Notebook [TODO: link]. -->


# Installation
ROICaT works on Windows, MacOS, and Linux. If you have any issues during the
installation process, please make a [github
issue](https://github.com/RichieHakim/ROICaT/issues) with the error.

### 0. Requirements
- [Anaconda](https://www.anaconda.com/distribution/) or
  [Miniconda](https://docs.conda.io/en/latest/miniconda.html).
- If using Windows: [Microsoft C++ Build
  Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/)
- The below commands should be run in the terminal (Mac/Linux) or Anaconda
  Prompt (Windows).

### 1. (Recommended) Create a new conda environment
```
conda create -n roicat python=3.12
conda activate roicat
```
You will need to activate the environment with `conda activate roicat` each time
you want to use ROICaT.

### 2. Install ROICaT
```
pip install roicat[all]
pip install git+https://github.com/RichieHakim/roiextractors
```
**Note on zsh:** if you are using a zsh terminal, change command to: `pip3
install --user 'roicat[all]'` <br>
**Note on installing GPU support on Windows:** see
[GPU Troubleshooting](https://roicat.readthedocs.io/en/latest/installation.html#gpu-support-issues)
documentation.
<br>
**Note on opencv:** The headless version of opencv is installed by default. If
the regular version is already installed, you will need to uninstall it first.

### 3. Clone the repo to get the notebooks
```
git clone https://github.com/RichieHakim/ROICaT
```
Then, navigate to the `ROICaT/notebooks/jupyter` directory to run the notebooks.


# Upgrading versions
There are 2 parts to upgrading ROICaT: the **Python package** and the
**repository files** which contain the notebooks and scripts.\
Activate your environment first, then...\
To upgrade the Python package, run:
```
pip install --upgrade roicat[all]
```
To upgrade the repository files, navigate your terminal to the `ROICaT` folder and run:
```
git pull
```


# General workflow:
- **Pass ROIs through ROInet:** Images of the ROIs are passed through a neural
  network which outputs a feature vector for each image describing what the ROI
  looks like.
-  **Classification:** The feature vectors can then be used to classify ROIs:
   - A simple regression-like classifier can be trained using user-supplied
     labeled data (e.g. an array of images of ROIs and a corresponding array of
     labels for each ROI).
   - Alternatively, classification can be done by projecting the feature vectors
     into a lower-dimensional space using UMAP and then simply circling the
     region of space to classify the ROIs.
-  **Tracking**: The feature vectors can be combined with information about the
   position of the ROIs to track the ROIs across imaging sessions/planes.


# Run the app locally
Although, we recommend transitioning to using the notebooks or CLI instead of the app, you can download and run the app locally with the following command:
```
sudo docker run -it -p 7860:7860 --platform=linux/amd64 --shm-size=10g registry.hf.space/richiehakim-roicat-tracking:latest streamlit run app.py
```


# TODO:
#### algorithmic improvements:
- [ ] Add in method to use more similarity metrics for tracking
- [ ] Coordinate descent on each similarity metric
- [ ] Add F and Fneu to data_roicat, dFoF and trace quality metric functions
- [ ] Add in notebook for demonstrating using temporal similarity metrics (SWT on dFoF)
- [ ] Make a standard classifier
- [ ] Try other clustering methods
- [x] Make image aligner based on image similarity + RANSAC of centroids or s_SF
- [ ] Better post-hoc curation metrics and visualizations
- [ ] Discount the non-rigid warp masks towards the edges to be more like the rigid warp map in order improve border performance
- [ ] Make non-rigid image registration optional
#### code improvements:
- [ ] **Finish ROIextractors integration**
- [ ] Update automatic regression module (make new repo for it)
- [ ] Switch to ONNX for ROInet
- [ ] Some more integration tests
- [ ] Figure out RNG / OS differences issues for tests
- [ ] Add more documentation / tutorials
- [x] Make a GUI
- [ ] Add settings to the GUI
- ~~[ ] Make a Docker container~~
- ~~Make colab demo notebook not require user data~~
- [x] Make a better CLI
- [ ] Switch to pyproject.toml
- [ ] Improve params.json / default params system
- [ ] Spruce up training code
- [ ] Switch off pickling optuna save file
- [ ] Try training on cellpose datasets
#### other:
- [ ] Write the paper
- [ ] Make tweet about it
- [ ] Make a video or two on how to use it
- [ ] Maybe use lightthetorch for torch installation
- [ ] Better Readme
- [ ] More documentation
- [ ] Make a regression model for in-plane-ness
- [ ] Formalize bounty program
