Skip to content
Open
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
157 changes: 157 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Copilot Instructions for replay_trajectory_classification

## Repository Summary

`replay_trajectory_classification` is a Python package for decoding spatial position from neural activity and categorizing trajectory types, specifically designed for analyzing hippocampal replay events in neuroscience research. The package provides state-space models that can decode position from both spike-sorted cells and clusterless spikes, with support for GPU acceleration and complex 1D/2D environments.

## High-Level Repository Information

- **Size**: ~63MB with 28 Python files
- **Type**: Scientific Python package for computational neuroscience
- **Primary Language**: Python 3.11+ (configured for Python 3.13 in current environment)
- **Key Dependencies**: NumPy, SciPy, scikit-learn, numba, xarray, dask, matplotlib, pandas
- **Documentation**: Sphinx-based documentation with ReadTheDocs hosting
- **License**: MIT

## Environment Setup and Build Instructions

### Prerequisites
Always use conda for environment management due to complex scientific dependencies:

```bash
# Update conda first (required)
conda update -n base conda

# Create environment from environment.yml (required)
conda env create -f environment.yml

# Activate environment
conda activate replay_trajectory_classification
```

### Installation Commands
**ALWAYS install in development mode for code changes:**

```bash
# Development installation (preferred)
python setup.py develop
# OR alternatively:
pip install -e .
```

**Note**: The `setup.py develop` command shows deprecation warnings but works correctly. Modern pip with `-e` flag is recommended.

### Validation Commands

#### Package Import Test
```bash
python -c "import replay_trajectory_classification; print('Package imported successfully')"
```
**Expected output**: "Cupy is not installed or GPU is not detected. Ignore this message if not using GPU" followed by "Package imported successfully"

#### Linting
```bash
flake8 replay_trajectory_classification/ --max-line-length=88 --select=E9,F63,F7,F82 --show-source --statistics
```
**Expected**: No output (clean lint)

#### Notebook Testing (CI Validation)
The main test suite runs Jupyter notebooks. Test individual notebooks:
```bash
jupyter nbconvert --to notebook --ExecutePreprocessor.kernel_name=python3 --execute notebooks/tutorial/01-Introduction_and_Data_Format.ipynb --output-dir=/tmp
```
**Time required**: ~2-3 minutes per notebook
**Expected**: Notebook executes without errors

#### Documentation Build
```bash
# First install docs dependencies
pip install -r docs/requirements-docs.txt

# Note: Documentation build has dependency issues with jupytext in Makefile
# The docs can be built but require manual intervention
```

## Continuous Integration

The repository uses GitHub Actions (`.github/workflows/PR-test.yml`):
- **Trigger**: All pushes
- **OS**: Ubuntu latest only
- **Python**: 3.11 (but environment.yml uses current conda defaults)
- **Test Process**: Executes all 5 tutorial notebooks sequentially
- **Environment**: Uses conda with channels: conda-forge, franklab, edeno
- **Installation**: `pip install -e .` after conda environment setup

## Project Architecture and Layout

### Core Package Structure (`replay_trajectory_classification/`)
- **`__init__.py`**: Main API exports (ClassifierBase, Decoders, Environment, etc.)
- **`classifier.py`**: Base classes for trajectory classification with both sorted/clusterless approaches
- **`decoder.py`**: Core decoding functionality
- **`environments.py`**: Spatial environment representation with discrete grids
- **`core.py`**: Low-level computational functions
- **`likelihoods/`**: Subpackage with various likelihood models (KDE, GLM, multiunit, GPU variants)

### Key Configuration Files
- **`environment.yml`**: Conda environment specification with scientific computing stack
- **`setup.py`**: Package configuration and dependencies
- **`.readthedocs.yaml`**: Documentation build configuration
- **`docs/conf.py`**: Sphinx documentation configuration
- **`docs/requirements-docs.txt`**: Documentation build dependencies

### Documentation (`docs/`)
- **Sphinx-based** with ReadTheDocs hosting
- **API docs**: Auto-generated from docstrings
- **Installation guide**: `installation.md`
- **Build system**: Makefile (but has jupytext dependency issues)

### Tutorials (`notebooks/tutorial/`)
Five comprehensive Jupyter notebooks demonstrate package usage:
1. **01-Introduction_and_Data_Format.ipynb**: Data format requirements
2. **02-Decoding_with_Sorted_Spikes.ipynb**: Single movement model with sorted spikes
3. **03-Decoding_with_Clusterless_Spikes.ipynb**: Single movement model with clusterless approach
4. **04-Classifying_with_Sorted_Spikes.ipynb**: Multiple movement models with sorted spikes
5. **05-Classifying_with_Clusterless_Spikes.ipynb**: Multiple movement models with clusterless spikes

### Dependencies Not Obvious from Structure
- **track_linearization**: External package for spatial track handling (imported in `__init__.py`)
- **regularized_glm**: Custom GLM implementation
- **GPU dependencies**: CuPy for GPU acceleration (optional)
- **franklab & edeno conda channels**: Required for specialized neuroscience packages

## Important Development Notes

### Environment Requirements
- **ALWAYS** use the conda environment - pip-only installations will fail due to complex scientific dependencies
- **GPU support** requires CuPy installation (optional, warnings are normal without GPU)
- **Documentation builds** may require manual intervention due to jupytext path issues

### Testing Approach
- **Integration testing**: All 5 tutorial notebooks must execute successfully
- **CI dependency**: Notebooks test real scientific workflows, not isolated functions

### Common Issues and Workarounds
- **Documentation build**: Makefile expects jupytext in PATH but may not find conda environment version
- **Setup.py warnings**: Deprecation warnings are expected but installation succeeds
- **GPU warnings**: "Cupy not installed" messages are normal for CPU-only environments
- **Long notebook execution**: Tutorial notebooks can take 2-3 minutes each to execute

### File Exclusions (from .gitignore)
Key files to exclude from commits:
- Jupyter checkpoint files (`.ipynb_checkpoints`)
- Build artifacts (`_build`, `_autosummary`, `dist/`)
- Data files (`*.mat`, `*.csv`, `*.nc`)
- Cache files (`__pycache__`, `*.prof`)

## Validation Checklist for Changes

1. **Environment setup**: Conda environment creates successfully
2. **Installation**: `python setup.py develop` or `pip install -e .` succeeds
3. **Import test**: Package imports without errors (GPU warnings OK)
4. **Lint check**: flake8 passes with specified parameters
5. **Notebook execution**: All tutorial notebooks run successfully
6. **CI compatibility**: Changes don't break the GitHub Actions workflow

## Final Note

This package serves active neuroscience research. Changes should maintain scientific accuracy and computational efficiency. The codebase prioritizes correctness over traditional software engineering practices (hence notebook-based testing). Trust these instructions and only search for additional information if specific technical details are missing or incorrect.
136 changes: 99 additions & 37 deletions .github/workflows/PR-test.yml
Original file line number Diff line number Diff line change
@@ -1,46 +1,108 @@
name: PR Test

on: push
on:
push:
branches: [ main, master ]
paths-ignore:
- '**.md'
- 'docs/**'
pull_request:
branches: [ main, master ]
paths-ignore:
- '**.md'
- 'docs/**'

# Auto-cancel in-progress runs for the same branch/PR
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

# Principle of least privilege
permissions:
contents: read

jobs:
run-tests:
name: Tests (${{ matrix.os }} • py${{ matrix.python }})
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest] #, macos-latest, windows-latest]
env:
OS: ${{ matrix.os }}
PYTHON: '3.11.*'
os: [ ubuntu-latest ] # add macos-latest, windows-latest as needed
python: [ "3.11" ]

steps:
- name: Cancel Workflow Action
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.11.*'
- name: Set up conda environment
uses: conda-incubator/setup-miniconda@v2
with:
python-version: '3.11.*'
miniforge-version: latest
use-mamba: true
channels: conda-forge,franklab,edeno
channel-priority: true
activate-environment: replay_trajectory_classification
environment-file: environment.yml
- name: Install replay_trajectory_classification
shell: bash -l {0}
run: |
pip install -e .
- name: Test notebooks
shell: bash -l {0}
run: |
jupyter nbconvert --to notebook --ExecutePreprocessor.kernel_name=python3 --execute notebooks/tutorial/01-Introduction_and_Data_Format.ipynb
jupyter nbconvert --to notebook --ExecutePreprocessor.kernel_name=python3 --execute notebooks/tutorial/02-Decoding_with_Sorted_Spikes.ipynb
jupyter nbconvert --to notebook --ExecutePreprocessor.kernel_name=python3 --execute notebooks/tutorial/03-Decoding_with_Clusterless_Spikes.ipynb
jupyter nbconvert --to notebook --ExecutePreprocessor.kernel_name=python3 --execute notebooks/tutorial/04-Classifying_with_Sorted_Spikes.ipynb
jupyter nbconvert --to notebook --ExecutePreprocessor.kernel_name=python3 --execute notebooks/tutorial/05-Classifying_with_Clusterless_Spikes.ipynb
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

# Use Miniforge + mamba for faster, reproducible env solves
- name: Set up Conda (Miniforge)
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
use-mamba: true
auto-update-conda: false
auto-activate-base: false
channel-priority: strict
channels: conda-forge,franklab,edeno
activate-environment: replay_trajectory_classification
environment-file: environment.yml
python-version: ${{ matrix.python }}

# Cache conda packages to speed up solves
- name: Cache conda pkgs
uses: actions/cache@v4
with:
path: ~/.conda/pkgs
key: ${{ runner.os }}-conda-${{ hashFiles('environment.yml') }}
restore-keys: |
${{ runner.os }}-conda-
- name: Show Conda info
shell: bash -l {0}
run: |
conda info
conda list
- name: Install package (editable)
shell: bash -l {0}
run: |
python -V
pip install --upgrade pip
pip install -e .
# Execute tutorial notebooks to ensure they run end-to-end
- name: Test notebooks
shell: bash -l {0}
env:
NB_KERNEL: python3
run: |
set -euo pipefail
for nb in \
notebooks/tutorial/01-Introduction_and_Data_Format.ipynb \
notebooks/tutorial/02-Decoding_with_Sorted_Spikes.ipynb \
notebooks/tutorial/03-Decoding_with_Clusterless_Spikes.ipynb \
notebooks/tutorial/04-Classifying_with_Sorted_Spikes.ipynb \
notebooks/tutorial/05-Classifying_with_Clusterless_Spikes.ipynb
do
echo "Executing $nb"
jupyter nbconvert \
--to notebook \
--inplace \
--ExecutePreprocessor.kernel_name="$NB_KERNEL" \
--ExecutePreprocessor.timeout=1800 \
--execute "$nb"
done
# Always upload executed notebooks to aid debugging
- name: Upload executed notebooks
if: always()
uses: actions/upload-artifact@v4
with:
name: executed-notebooks-${{ matrix.os }}-py${{ matrix.python }}
path: |
notebooks/tutorial/*.ipynb
if-no-files-found: warn
143 changes: 80 additions & 63 deletions notebooks/tutorial/01-Introduction_and_Data_Format.ipynb

Large diffs are not rendered by default.

957 changes: 830 additions & 127 deletions notebooks/tutorial/03-Decoding_with_Clusterless_Spikes.ipynb

Large diffs are not rendered by default.

773 changes: 700 additions & 73 deletions notebooks/tutorial/05-Classifying_with_Clusterless_Spikes.ipynb

Large diffs are not rendered by default.

3,131 changes: 2,139 additions & 992 deletions notebooks/work_in_progress/Test_Inbound_Outbound.ipynb

Large diffs are not rendered by default.

3,562 changes: 2,599 additions & 963 deletions notebooks/work_in_progress/Test_Inbound_Outbound_Directionality.ipynb

Large diffs are not rendered by default.

Loading