Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Subgrid Optimization

SubgridOptimization is a Python package for spatially constrained channel selection in high-density ECoG decoding. It is based on the methodology described in the manuscript Optimal Size and Placement of Electrocorticography Grids for Classification of Hand Movements. The package searches for compact axis-aligned rectangular electrode subgrids that preserve decoding performance while reducing grid size and implantation footprint.

The repository currently provides two optimization strategies:

  • SpatialExhaustiveSearch, which evaluates all admissible rectangular subgrids of a grid
  • SpatialStochasticHillClimbing, which approximates the search by iterative stochastic expansion of rectangular subgrids

In addition, the package provides utilities for performance-size and channel-importance analysis:

  • elimination_plot, which summarizes decoding performance as a function of retained grid size, expressed either as channel count or estimated physical area
  • importance_plot, which estimates channel relevance by averaging the decoding scores of all evaluated subgrids that include a given electrode

Features

  • exhaustive and stochastic search strategies rectangular subgrid optimization under explicit spatial constraints

  • visualization for performance-size analysis and channel-importance mapping from evaluated subgrids

  • compatibility with standard scikit-learn estimators and pipelines

A. Installation

Requirements

The package is tested with:

  • Python 3.9
  • Linux

The core runtime dependencies are:

  • numpy
  • scipy
  • scikit-learn
  • matplotlib
  • pandas
  • tqdm

Option 1. Install from source

Clone the repository and install it into a local Python environment.

git clone https://github.com/DirkKeller/Subgrid-Optimization.git
cd Subgrid-Optimization
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip

Install directly from the project metadata:

pip install -e .

or manually:

pip install "numpy>=1.25,<2.0" "pandas>=1.5,<3.0" "scipy>=1.11,<2.0" "scikit-learn>=1.3,<1.5" "matplotlib>=3.7,<4.0" "seaborn>=0.13,<0.14" "tqdm>=4.66,<5.0"

Option 2. Run with Docker

Build the image:

docker build -t subgrid-optimization .

Run the synthetic example:

docker run --rm -it subgrid-optimization

Run the example and write outputs to your local machine:

mkdir -p output
docker run --rm -it \
  -v "$(pwd)/output:/app/output" \
  subgrid-optimization

Open an interactive shell inside the container:

docker run --rm -it subgrid-optimization /bin/bash

B. Quick start

The example below demonstrates the basic estimator interface on synthetic input with the expected tensor shape [samples, height, width, time].

import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import SVC

from subopt.exhaustive import SpatialExhaustiveSearch

# Example data
X = np.random.randn(100, 8, 8, 20)
y = np.random.randint(0, 3, size=100)
grid =  np.arange(1, 65).reshape(X.shape[1:3])

estimator = Pipeline([
    ("scaler", MinMaxScaler()),
    ("clf", SVC(kernel="linear"))
])

optimizer = SpatialExhaustiveSearch(
    estimator=estimator,
    grid=grid,
    metric="f1_weighted",
    cv=5
)

optimizer.fit(X, y)
print(optimizer.score_)
print(optimizer.mask_)

C. Synthetic example

The included example examples/synth_data.py generates a structured synthetic hand-movement decoding dataset without requiring external recordings. It is intended as a realistic test bed for validating the search procedures and visual outputs.

  • 8x8 spatial grid
  • event-locked epochs from -0.5 s to 1.5 s
  • realistic low-frequency drift and temporally correlated channel noise
  • partially overlapping class-specific motor hotspots for thumb, index, and little finger
  • shared activation around a central-sulcus band to mimic overlapping sensorimotor representations
  • weighted-F1 scoring with a linear SVM and stratified cross-validation

Run it with:

python examples/synth_data.py

The script writes outputs to ./output/synthetic_example/, including:

  • synthetic_results.csv
  • optimizer-specific elimination plots
  • optimizer-specific importance plots
  • a summary of the implanted synthetic hotspots

D. Algorithm summary

1. Spatial exhaustive search

The exhaustive algorithm enumerates every rectangular subgrid that can be embedded within the original grid and evaluates each candidate with cross-validation.

For a grid with width W and height H, the number of rectangular subgrids is:

$$T_g = \sum_{i=1}^{W} \sum_{j=1}^{H} (W - i + 1)(H - j + 1)$$

2. Spatial stochastic hill climbing

The stochastic optimizer starts from random seed electrodes and expands a rectangular subgrid one valid direction at a time. Expansion alternates between:

  • exploration, where a candidate direction is sampled randomly
  • exploitation, where all valid candidate directions are scored and the best one is selected

This produces an efficient approximation when exhaustive search is computationally expensive.

Input data expectations

The optimizers expect input data with the following shape conventions:

  • X.shape = [samples, channel_height, channel_width, time]
  • y.shape = [samples]

When a grid definition is provided, it should preserve the spatial arrangement of channels and uniquely encode channel identity.

3. Performance-area analysis

Each algorithm possesses an elimination_plot, which visualizes performance against either channel count or estimated physical area. In the accompanying paper, subgrid surface area is computed from electrode spacing and exposed diameter, and performance-area curves are used to identify a knee-point where accuracy begins to decline more sharply.

Performance-area example

4. Channel-importance maps

Morover, the importance_plot function implements the same general idea as the paper’s informative-electrode analysis. Each electrode is assigned the mean performance of all subgrids containing that electrode, which yields a participant-specific spatial importance map.

Channel importance maps

E. Project Structure

SubgridOptimization/
├── pyproject.toml
├── Dockerfile
├── README.md
├── LICENSE
├── .gitignore
├── opt/
│   ├── __init__.py
│   ├── base.py
│   ├── exhaustive.py
│   ├── hillclimbing.py
│   └── utils.py
├── examples/
│   └── synth_data.py
└── docs/
    └── figures/
        ├── paper_fig1.png
        └── paper_fig2.png

F. Citation

If you use this repository, please cite the associated manuscript and the software repository.

@article{keller2026optimal,
  author = {Keller, Dirk and Offenberg, Elena C. and Mehrkanoon, Siamak and Berezutskaya, Julia and Vansteensel, Mariska J. and Branco, Mariana P.},
  title = {Optimal Size and Placement of Electrocorticography Grids for Classification of Hand Movements},
  year = {2026},
  journal = {To be added},
  doi = {To be added}
}

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages