INTENSE: Information-Theoretic Evaluation of Neuronal Selectivity
INTENSE is a computational framework for analyzing neuronal selectivity to behavioral and environmental variables using information theory. It quantifies the relationship between neural signals (calcium imaging, spike trains) and external variables through mutual information analysis with rigorous statistical testing.
Overview
INTENSE addresses a fundamental question in neuroscience: which neurons encode specific behavioral or environmental variables? By using mutual information (MI) as the core metric, INTENSE can detect both linear and nonlinear relationships between neural activity and external variables.
The key advantage of MI over traditional correlation measures is its ability to capture any statistical dependency:
Linear relationships (captured by Pearson correlation)
Monotonic relationships (captured by Spearman correlation)
Complex nonlinear dependencies (only captured by MI)
Key features
Mutual Information Analysis: Quantifies statistical dependencies between neural signals and behavioral variables
Two-Stage Statistical Testing: Efficient hypothesis testing with multiple comparison correction
Optimal Delay Detection: Accounts for temporal delays between neural activity and behavior
Mixed Selectivity Analysis: Disentangles relationships when neurons respond to multiple correlated variables
Multiple Metrics Support: MI, Spearman correlation, and other similarity metrics
Parallel Processing: Efficient computation for large-scale neural datasets
Quick start
Analyze neuronal selectivity with synthetic data:
import driada
# Generate synthetic experiment with place cells and behavioral features
exp = driada.generate_synthetic_exp(
n_dfeats=2, # discrete features (e.g., trial type)
n_cfeats=2, # continuous features (e.g., x, y position)
nneurons=20, # number of neurons
duration=300, # 5 minutes recording
seed=42
)
# Discover significant neuron-feature relationships
stats, significance, info, results, _ = driada.compute_cell_feat_significance(
exp,
mode='two_stage',
n_shuffles_stage1=50, # preliminary screening
n_shuffles_stage2=1000, # validation (use 10000+ for publication)
verbose=True
)
# Use Experiment method to get significant neurons
significant_neurons = exp.get_significant_neurons()
print(f"Found {len(significant_neurons)} significant neuron-feature pairs")
# Examine results using Experiment methods
for cell_id in list(significant_neurons.keys())[:3]: # Show first 3 neurons
for feat_name in significant_neurons[cell_id]:
pair_stats = exp.get_neuron_feature_pair_stats(cell_id, feat_name)
print(f"Neuron {cell_id} - Feature '{feat_name}':")
print(f" Rank value (Stage 1): {pair_stats['pre_rval']:.4f}")
if 'pval' in pair_stats:
print(f" P-value: {pair_stats['pval']:.2e}")
print(f" Optimal delay: {pair_stats.get('opt_delay', 0)} frames")
Expected output:
Found 8 significant neuron-feature pairs
Neuron 3 - Feature 'c_feat_0':
Rank value (Stage 1): 0.9901
P-value: 2.45e-05
Optimal delay: 3 frames
Visualization:
import matplotlib.pyplot as plt
# Plot neuron-feature relationship for first significant pair
if significant_neurons:
cell_id = list(significant_neurons.keys())[0]
feat_name = significant_neurons[cell_id][0]
fig, ax = plt.subplots(figsize=(8, 5))
driada.intense.plot_neuron_feature_pair(exp, cell_id, feat_name, ax=ax)
plt.title(f"Neuron {cell_id} selectivity to {feat_name}")
plt.show()
Using your own data
The Experiment class is the main data container throughout DRIADA. It holds neural recordings, behavioral variables, and analysis results in a unified structure.
Creating an Experiment from your data
import numpy as np
import driada
# Your neural data
calcium_traces = np.random.randn(100, 12000) # 100 neurons, 12000 timepoints
spike_times = None # Optional: spike trains (same shape as calcium)
# Your behavioral variables (dynamic features)
x_position = np.random.randn(12000) # x coordinate over time
y_position = np.random.randn(12000) # y coordinate over time
trial_type = np.random.randint(0, 2, 12000) # discrete: 0=left, 1=right trials
speed = np.abs(np.random.randn(12000)) # continuous: movement speed
dynamic_features = {
'x': x_position,
'y': y_position,
'trial_type': trial_type,
'speed': speed
}
# Experimental metadata (static features)
static_features = {
'fps': 20.0, # sampling rate (frames per second)
't_rise_sec': 0.5, # calcium rise time
't_off_sec': 2.0 # calcium decay time
}
# Experiment identifiers
exp_identificators = {
'session': 'session_001',
'animal': 'mouse_123'
}
# Create Experiment object
exp = driada.Experiment(
signature='MyExperiment',
calcium=calcium_traces,
spikes=spike_times, # Can be None
exp_identificators=exp_identificators,
static_features=static_features,
dynamic_features=dynamic_features
)
print(f"Created experiment with {exp.n_cells} neurons and {exp.n_frames} timepoints")
# Now analyze with INTENSE
stats, significance, info, results, _ = driada.compute_cell_feat_significance(exp)
Key points:
calcium: Neural activity traces (numpy array, shape: n_neurons × n_timepoints)
dynamic_features: Behavioral variables that change over time (dict of numpy arrays)
static_features: Experimental parameters (dict with ‘fps’, ‘t_rise_sec’, ‘t_off_sec’)
spikes: Optional spike trains (can be None to auto-detect from calcium using wavelets)
The Experiment automatically converts numpy arrays to TimeSeries objects internally
All subsequent DRIADA analysis uses this unified Experiment container
Mathematical framework
Mutual information computation
INTENSE uses Gaussian Copula Mutual Information (GCMI) for robust MI estimation. The mutual information between two random variables X and Y is defined as:
I(X;Y) = ∫∫ p(x,y) log[p(x,y)/(p(x)p(y))] dx dy
Equivalently, using entropy notation:
I(X;Y) = H(X) + H(Y) - H(X,Y)
where H(X) = -∫ p(x) log p(x) dx is the differential entropy.
Gaussian copula transformation
The GCMI method leverages the copula representation of joint distributions. The key insight is that MI is invariant under monotonic transformations, allowing us to transform to a convenient representation:
Empirical CDF transformation: For each variable, compute the empirical cumulative distribution function:
F_X(x) = (rank(x) + 0.5) / N
Gaussian transformation: Apply the inverse normal CDF:
X̃ = Φ^(-1)(F_X(X)) Ỹ = Φ^(-1)(F_Y(Y))
MI estimation: For the Gaussian copula, MI has a simple form:
I_GCMI(X;Y) = -0.5 log|R|
where R is the correlation matrix of (X̃, Ỹ).
Handling different variable types
Continuous-Continuous Case: Direct application of GCMI formula above.
Discrete-Continuous Case: For discrete X with K states and continuous Y:
I(X;Y) = Σ_{k=1}^K p(X=k) · H(Y) - Σ_{k=1}^K p(X=k) · H(Y|X=k)
Each conditional entropy H(Y|X=k) is computed using GCMI on the subset where X=k.
Statistical significance testing
Significance is assessed by comparing observed MI against a null distribution generated from time-shuffled signals:
MI_shuffle^(i) = I(X(t); Y(t + τᵢ))
where τᵢ represents random circular shifts preserving the temporal structure of individual signals while destroying their correlation.
Parametric null distribution modeling
The null distribution of shuffled MI values is modeled using a parametric distribution. The gamma distribution is the default choice due to:
Non-negativity of MI values
Right-skewed nature of MI distributions
Theoretical support from information theory
The gamma distribution parameters are estimated via maximum likelihood:
MI_shuffle ~ Γ(α, β)
p(MI|α,β) = (β^α/Γ(α)) · MI^(α-1) · exp(-β·MI)
The p-value is computed as:
p-value = P(MI_shuffle ≥ MI_observed) = 1 - F_Γ(MI_observed; α̂, β̂)
where F_Γ is the cumulative distribution function of the fitted gamma distribution.
Noise addition for numerical stability
When using the standard gamma distribution, a small amount of noise (10^-3) is added
to MI values to prevent numerical issues with identical values and improve distribution
fitting. When using the default gamma_zi distribution, noise is not added because the
zero-inflated model handles zero MI values explicitly.
Rank values (r-vals) and non-parametric testing
INTENSE employs a dual approach combining parametric and non-parametric methods:
Rank Values (r-vals): For each neuron-feature pair, INTENSE computes the rank of the observed MI value within the null distribution:
r-val = rank(MI_observed) / (n_shuffles + 1)
The r-val represents the proportion of shuffled MI values that are lower than the observed MI. This is equivalent to computing an empirical p-value:
empirical_p_value = 1 - r-val
Advantages of r-vals:
Distribution-free: No assumptions about the shape of the MI distribution
Robust: Unaffected by outliers or distribution fitting failures
Conservative: The (n_shuffles + 1) denominator prevents p-values of exactly 0
Dual Criterion for Significance: INTENSE requires both criteria to be met:
Non-parametric criterion: r-val > (1 - k/(n_shuffles + 1)), typically k=5
Parametric criterion: p-value < threshold (after multiple comparison correction)
This dual approach provides robustness:
The r-val criterion ensures the observed MI is genuinely in the extreme tail
The parametric p-value provides a continuous measure of significance
Both must pass, preventing false positives from poor distribution fits
Two-stage testing procedure
The two-stage approach balances computational efficiency with statistical rigor:
Stage 1: Screening (100 shuffles)
Criterion: MI_observed > max{MI_shuffle^(i)}_{i=1}^{100}
Purpose: Early rejection of non-significant pairs
False negative rate: < 1% for truly significant pairs
Computational savings: ~100x for rejected pairs
Stage 2: Validation (10,000 shuffles)
Applied to: Pairs passing Stage 1
Criteria:
Rank criterion: MI_observed > 99.95th percentile of shuffles
Parametric test: p-value < threshold (after multiple comparison correction)
Multiple comparison correction
The Holm-Bonferroni method is used to control family-wise error rate (FWER):
Order p-values: p₁ ≤ p₂ ≤ … ≤ pₘ
For the k-th hypothesis, use threshold:
α_k = α / (m - k + 1)
where α = 0.01 (FWER) and m = number of hypotheses from Stage 1
Reject hypotheses while p_k < α_k; stop at first failure
This provides strong FWER control while being more powerful than standard Bonferroni correction.
Optimal delay detection
Neural activity often shows temporal delays relative to behavior due to:
Calcium indicator dynamics (~1-2s delay for GCaMP)
Predictive coding (activity preceding behavior)
Sensory processing delays
INTENSE finds the optimal delay by maximizing MI:
δ_optimal = argmax_{δ} I(X(t); Y(t + δ))
MI_optimal = I(X(t); Y(t + δ_optimal))
where:
δ ∈ [-W, +W], typically W = 2 seconds
Resolution: Δδ = 0.05 seconds (or 1/fps)
Search space: 80 delay values for 2s window
The significance testing uses the optimally delayed signals, accounting for the multiple comparison issue in delay selection.
FFT-accelerated permutation testing
The two-stage procedure requires evaluating MI at thousands of circular shifts per neuron-behavior pair. A naive implementation recomputes MI independently for each shift, yielding a per-pair cost of $O(n_{\text{sh}} \cdot n)$ where $n$ is the number of time frames and $n_{\text{sh}}$ the number of shuffles. For a typical experiment with $N$ neurons, $M$ behavioral features, $D$ delay steps, and $n_{\text{sh}} = 10{,}000$ shuffles, this becomes prohibitive.
INTENSE exploits the fact that circular time shifts correspond to circular cross-correlations, which can be computed for all $n$ possible shifts simultaneously via the convolution theorem:
$$C_{XY}[s] = \sum_{i=0}^{n-1} X[i] , Y[(i+s) \bmod n] = \mathcal{F}^{-1}!\bigl[\mathcal{F}[X] \cdot \mathcal{F}[Y]^{*}\bigr][s]$$
where $\mathcal{F}$ denotes the discrete Fourier transform and $^{*}$ complex conjugation. This reduces the cost from $O(n_{\text{sh}} \cdot n)$ to $O(n \log n)$ for computing MI at all shifts, after which any specific shift is an $O(1)$ array lookup. The particular form of MI at each shift depends on the variable types:
Continuous–continuous case. For copula-normalized Gaussian variables, MI reduces to $I(X; Y_s) = -\tfrac{1}{2}\log_2(1 - r(s)^2)$ where $r(s)$ is the Pearson correlation at shift $s$. The correlation for all shifts is obtained as $r(s) = C_{XY}[s] / [(n-1),\sigma_X \sigma_Y]$, requiring a single pair of real-valued FFTs.
Continuous–discrete case. For a continuous variable $Z$ and a discrete variable $X$ with $K$ classes, class-conditional sums at every shift are circular correlations with indicator functions:
$$\sum_i Z[i] \cdot \mathbb{1}[X_{(i+s)} = k] = \mathcal{F}^{-1}[\mathcal{F}[Z] \cdot \mathcal{F}[\mathbb{1}_{X=k}]^{*}][s]$$
From these sums and the analogous sums of $Z^2$, class-conditional variances and Gaussian entropies are computed for all shifts simultaneously, yielding MI via $I = H(Z) - \sum_k p(k),H(Z | X!=!k)$. This requires $2K+2$ FFTs (for $Z$, $Z^2$, and $K$ indicator functions), independent of the number of shuffles.
Discrete–discrete case. Contingency tables for all shifts are obtained via indicator cross-correlations: $n_{ij}(s) = \mathcal{F}^{-1}[\mathcal{F}[\mathbb{1}{X=i}] \cdot \mathcal{F}[\mathbb{1}{Y=j}]^{*}][s]$, requiring $K_X \cdot K_Y$ FFT pairs.
Multivariate case. For $d$-dimensional behavioral features (e.g., 2D spatial position), the joint covariance matrix separates into shift-invariant within-variable blocks and shift-dependent cross-covariance blocks computed via $d$ FFTs. MI is then evaluated through closed-form vectorized determinant formulas ($d \leq 3$).
FFT cache strategy
INTENSE precomputes MI for all $n$ shifts once per neuron-feature pair and stores the result in an FFT cache. This cache is reused across delay optimization, Stage 1 screening, and Stage 2 validation without recomputation. The total cost is $O(N \cdot M \cdot n \log n)$ for the cache build plus $O(N \cdot M \cdot n_{\text{sh}})$ for shift lookups, compared to $O(N \cdot M \cdot n_{\text{sh}} \cdot n)$ without acceleration.
Mixed selectivity analysis
Many neurons respond to multiple, often correlated behavioral variables. INTENSE disentangles these relationships using information-theoretic decomposition.
Conditional mutual information
For neural activity A and behavioral variables X, Y:
I(A;X|Y) = H(A|Y) - H(A|X,Y) = I(A;X,Y) - I(A;Y)
This quantifies information about A in X that is not present in Y.
Interaction information
The three-way interaction (synergy/redundancy) is measured using the Williams & Beer (2010) convention:
II(A;X;Y) = I(A;X|Y) - I(A;X) = I(A;Y|X) - I(A;Y)
II < 0: Redundancy (X and Y provide overlapping information about A)
II > 0: Synergy (X and Y together provide more information than separately)
Note: Interaction information (II) provides the net redundancy or synergy but does not decompose mutual information into unique, redundant, and synergistic components. A future Partial Information Decomposition (PID) module will provide this full decomposition.
Variable type handling
Both continuous: Use multivariate GCMI with Cholesky decomposition
X continuous, Y discrete: Compute I(A;X|Y=y) for each y, then average
X discrete, Y continuous: Use the identity I(A;X|Y) = I(A;X) - [I(A;Y) - I(A;Y|X)]
Both discrete: Standard discrete MI formulas with empirical probabilities
Interpretation framework
For negative II (common in neural data), we identify the “weakest” link:
If |I(A;X)| < |II|: X is redundant given Y
If |I(A;Y)| < |II|: Y is redundant given X
Otherwise: Both variables contribute independently
Usage example
from driada.intense.pipelines import compute_cell_feat_significance
# Analyze neuronal selectivity in an experiment
stats, significance, info, results, _ = compute_cell_feat_significance(
exp, # Experiment object
cell_bunch=None, # Analyze all neurons
feat_bunch=['speed', 'head_direction', 'x', 'y'], # Behavioral variables
metric='mi', # Use mutual information
mode='two_stage', # Two-stage testing
n_shuffles_stage1=100, # Stage 1 shuffles
n_shuffles_stage2=10000,# Stage 2 shuffles
pval_thr=0.01, # Significance threshold
find_optimal_delays=True,
shift_window=2 # ±2 second delay window
)
Output
INTENSE provides:
Statistical measures: MI values, p-values, optimal delays
Significance results: Which neuron-behavior pairs are significant
Diagnostic information: Shuffle distributions, test statistics
Applications
Place cell identification in navigation experiments
Feature selectivity in sensory neurons
Task-relevant neural encoding in cognitive experiments
Population-level analysis of neural representations
Validation of computational models against neural data
Limitations and considerations
Statistical power
Stage 1 screening may miss weak but real effects (1% false negative rate)
Multiple comparison correction reduces power for large neuron populations
Minimum recommended recording length: 1000 timepoints per behavioral state
Computational considerations
Memory usage scales as O(N × M × S) for N neurons, M behaviors, S shuffles
Optimal delay search adds 40-80x computational overhead
Parallel processing recommended for >100 neurons
Methodological assumptions
Stationarity: Assumes stable neuron-behavior relationships
Temporal resolution: Limited by sampling rate (calcium imaging: ~10-30 Hz)
Shuffle validity: Assumes temporal shifts destroy all dependencies
References
Key publications underlying INTENSE methodology:
Gaussian Copula MI: Ince, R. A., Giordano, B. L., Kayser, C., Rousselet, G. A., Gross, J., & Schyns, P. G. (2017). A statistical framework for neuroimaging data analysis based on mutual information estimated via a gaussian copula. Human brain mapping, 38(3), 1541-1573.
Information Theory in Neuroscience: Timme, N., Alford, W., Flecker, B., & Beggs, J. M. (2014). Synergy, redundancy, and multivariate information measures: an experimentalist’s perspective. Journal of computational neuroscience, 36(2), 119-140.
Interaction Information: Ghassami, A., Kiyavash, N., Huang, B., & Zhang, K. (2017). Multi-domain causal structure learning in linear systems. Advances in neural information processing systems, 30.
MI Distribution Theory: Hutter, M. (2001). Distribution of mutual information. Advances in neural information processing systems, 14.
Performance considerations
Parallel processing supported for large datasets
Downsampling available to reduce computational load
Caching of precomputed statistics for iterative analysis
Memory-efficient implementations for long recordings