Spatial Analysis Utilities
Spatial Analysis Utilities for Neural Data
This module provides comprehensive spatial analysis tools for neural data, particularly for analyzing place cells, grid cells, and other spatially-modulated neurons.
Key functionality: - Place field detection and analysis - Grid score computation - Spatial information metrics - Position decoding - Speed/direction filtering - High-level spatial analysis pipelines
Utilities for spatial data visualization and evaluation metrics.
Note
Place cell detection: Use driada.intense (MI-based analysis with
shuffle-based significance testing) for principled place cell detection.
extract_place_fields() is EXPERIMENTAL and uses arbitrary thresholds.
It’s provided for quick visualization only, not scientific analysis.
Warning
Removed in v1.0: analyze_spatial_coding() and filter_by_speed()
have been removed. Use INTENSE for place cell detection and analysis.
Visualization Utilities
Core functions for creating spatial visualizations:
- driada.utils.spatial.compute_occupancy_map(positions, fps=1.0, arena_bounds=None, bin_size=0.025, min_occupancy=0.1, smooth_sigma=None)[source]
Compute 2D occupancy map from position data.
- Parameters:
positions (np.ndarray, shape (n_samples, 2)) – X, Y positions over time
fps (float) – Frames per second (sampling frequency). Default 1.0 assumes one frame per second.
arena_bounds (tuple of tuples, optional) – ((x_min, x_max), (y_min, y_max)). If None, inferred from data
bin_size (float) – Size of spatial bins in same units as positions
min_occupancy (float) – Minimum occupancy time (seconds) for valid bins
smooth_sigma (float, optional) – Gaussian smoothing sigma in bins. If None, no smoothing
- Return type:
- Returns:
occupancy_map (np.ndarray) – 2D occupancy map in seconds
x_edges (np.ndarray) – X bin edges
y_edges (np.ndarray) – Y bin edges
- Raises:
ValueError – If positions is not 2D or fps is non-positive
Examples
>>> positions = np.random.rand(1000, 2) # 1000 frames >>> # With 30 fps recording >>> occ_map, x_edges, y_edges = compute_occupancy_map(positions, fps=30.0) >>> # occ_map contains time in seconds per bin
Compute time spent in each spatial bin. Use for trajectory occupancy maps.
- driada.utils.spatial.compute_rate_map(neural_signal, positions, occupancy_map, x_edges, y_edges, fps=1.0, smooth_sigma=1.5)[source]
Compute firing rate map from neural signal and positions.
- Parameters:
neural_signal (np.ndarray) – Neural signal (e.g., calcium fluorescence, firing rates, spike counts)
positions (np.ndarray, shape (n_samples, 2)) – X, Y positions corresponding to neural signal
occupancy_map (np.ndarray) – 2D occupancy map in seconds from compute_occupancy_map
x_edges (np.ndarray) – X bin edges from compute_occupancy_map
y_edges (np.ndarray) – Y bin edges from compute_occupancy_map
fps (float) – Frames per second (sampling frequency). Must match the fps used in compute_occupancy_map.
smooth_sigma (float, optional) – Gaussian smoothing sigma in bins
- Returns:
rate_map – 2D activity map (mean signal per spatial bin)
- Return type:
np.ndarray
- Raises:
ValueError – If positions shape doesn’t match neural_signal length or fps is non-positive
Examples
>>> # Generate sample data >>> import numpy as np >>> positions = np.random.rand(1000, 2) # 1000 frames of 2D positions >>> neural_signal = np.random.rand(1000) # Corresponding neural activity
>>> # Compute occupancy first >>> occ_map, x_edges, y_edges = compute_occupancy_map(positions, fps=30.0) >>> # Then compute rate map >>> rate_map = compute_rate_map(neural_signal, positions, occ_map, ... x_edges, y_edges, fps=30.0)
Compute firing rate as a function of position. Use for place field visualization.
Spatial Information Metrics
Evaluation metrics for spatial coding:
- driada.utils.spatial.compute_spatial_information_rate(rate_map, occupancy_map)[source]
Compute spatial information rate (bits/spike).
Implements Skaggs et al. (1993) spatial information metric.
- Parameters:
rate_map (np.ndarray) – 2D firing rate map
occupancy_map (np.ndarray) – 2D occupancy map in seconds (time spent in each bin)
- Returns:
spatial_info – Spatial information in bits/spike. Returns 0 if mean rate is 0.
- Return type:
Notes
Forces non-negative result. Uses log2 for bits.
Examples
>>> import numpy as np >>> positions = np.random.rand(1000, 2) >>> signal = np.random.rand(1000) # Neural signal >>> occ_map, x_edges, y_edges = compute_occupancy_map(positions, fps=30.0) >>> rate_map = compute_rate_map(signal, positions, occ_map, x_edges, y_edges, fps=30.0) >>> si = compute_spatial_information_rate(rate_map, occ_map)
Skaggs et al. (1993) spatial information metric in bits/spike. Measures how much information about position is conveyed by each spike.
- driada.utils.spatial.compute_spatial_information(neural_activity, positions, logger=None)[source]
Compute mutual information between neural activity and spatial position.
- Parameters:
neural_activity (array-like or TimeSeries) – Neural activity data. If np.ndarray, shape (n_neurons, n_samples) or (n_samples,)
positions (array-like or TimeSeries) – Spatial position data (X, Y). If np.ndarray, shape (n_samples, 2)
logger (logging.Logger, optional) – Logger for debugging
- Returns:
metrics – Spatial information metrics: - mi_x: MI with X position - mi_y: MI with Y position - mi_total: MI with 2D position
- Return type:
- Raises:
ValueError – If positions is not 2D or shape mismatch
ImportError – If required information theory packages are not available
Notes
Uses Gaussian-Copula MI (gcmi) estimator.
Examples
>>> import numpy as np >>> # Create sample data: 5 neurons, 500 time points >>> neural_data = np.random.rand(5, 500) >>> positions = np.random.rand(500, 2) >>> mi_metrics = compute_spatial_information(neural_data, positions) >>> print(f"MI with position: {mi_metrics['mi_total']:.3f} bits") MI with position: ... bits
Mutual information between neural activity and position. Returns MI for X, Y, and total 2D position.
- driada.utils.spatial.compute_spatial_decoding_accuracy(neural_activity, positions, test_size=0.5, n_estimators=20, max_depth=3, min_samples_leaf=50, random_state=42, logger=None)[source]
Compute position decoding accuracy from neural activity.
- Parameters:
neural_activity (np.ndarray, shape (n_neurons, n_samples)) – Neural activity matrix
positions (np.ndarray, shape (n_samples, 2)) – True X, Y positions
test_size (float) – Fraction of data for testing
n_estimators (int) – Number of trees in random forest
max_depth (int) – Maximum tree depth
min_samples_leaf (int) – Minimum samples per leaf
random_state (int) – Random seed for reproducibility
logger (logging.Logger, optional) – Logger for debugging
- Returns:
metrics – Decoding accuracy metrics: - r2_x: R² score for X position - r2_y: R² score for Y position - r2_avg: Average R² score - mse: Mean squared error
- Return type:
- Raises:
ValueError – If shape mismatch between neural_activity and positions
Notes
Forces non-negative R² scores. Uses all CPU cores.
Examples
>>> import numpy as np >>> # Create sample data: 10 neurons, 1000 time points >>> neural_data = np.random.rand(10, 1000) >>> positions = np.random.rand(1000, 2) >>> metrics = compute_spatial_decoding_accuracy(neural_data, positions) >>> print(f"Decoding R²: {metrics['r2_avg']:.3f}") Decoding R²: ...
ML-based position decoding from neural activity. Uses Random Forest regression to predict position from population activity.
Metrics Wrapper
- driada.utils.spatial.compute_spatial_metrics(neural_activity, positions, metrics=None, **kwargs)[source]
Compute selected spatial metrics (decoding and information only).
Note
Place field detection (extract_place_fields) is experimental and not included in this function. Use INTENSE for principled place cell detection.
- Parameters:
neural_activity (np.ndarray, shape (n_neurons, n_samples)) – Neural activity data
positions (np.ndarray, shape (n_samples, 2)) – Position data
metrics (list of str, optional) – Metrics to compute. If None, computes all. Options: ‘decoding’, ‘information’ (Removed: ‘place_fields’ - use INTENSE instead)
**kwargs – Additional arguments passed to analysis functions (e.g., fps, logger, test_size)
- Returns:
results – Computed metrics based on requested analyses
- Return type:
- Raises:
ValueError – If invalid metric name provided or ‘place_fields’ requested
Examples
>>> # Compute only decoding accuracy >>> import numpy as np >>> neural_data = np.random.rand(15, 2000) # 15 neurons, 2000 samples >>> positions = np.random.rand(2000, 2) >>> results = compute_spatial_metrics(neural_data, positions, ... metrics=['decoding']) >>> # Compute all metrics >>> import numpy as np >>> neural_data = np.random.rand(15, 2000) >>> positions = np.random.rand(2000, 2) >>> results = compute_spatial_metrics(neural_data, positions)
Compute multiple spatial metrics (decoding and information). Place field detection removed - use INTENSE instead.
Experimental Functions
Warning
The following function is EXPERIMENTAL and uses arbitrary thresholds. For scientific analysis, use INTENSE for principled place cell detection.
- driada.utils.spatial.extract_place_fields(rate_map, min_peak_rate=1.0, min_field_size=9, peak_to_mean_ratio=1.5)[source]
Extract place fields from a rate map using threshold-based detection.
Warning
This function is EXPERIMENTAL and uses arbitrary thresholds. For scientific analysis, use INTENSE (MI-based detection with shuffle-based significance testing).
This function is provided for quick visualization purposes only (e.g., “roughly where are the place fields for plotting?”). It should NOT be used for quantitative analysis.
- Parameters:
- Returns:
place_fields – List of place fields with properties: - peak_rate: Peak firing rate - center: (x, y) indices of field center - size: Number of bins in field - mean_rate: Mean rate within field
- Return type:
- Raises:
ValueError – If input parameters are invalid
Notes
Uses 8-connectivity for contiguous region detection.
Experimental function - thresholds are not data-driven. Use compute_cell_feat_significance() from INTENSE for principled detection.
Examples
>>> rate_map = np.random.rand(40, 40) >>> fields = extract_place_fields(rate_map, min_peak_rate=0.8)
EXPERIMENTAL: Threshold-based place field detection for visualization only. Uses arbitrary parameters (min_peak_rate, min_field_size, peak_to_mean_ratio). For quantitative analysis, use
compute_cell_feat_significance()from INTENSE.