Atomic Primitives — Design Philosophy
cogpy is a library of atomic, composable operators for electrophysiology signal processing. It is not a pipeline framework.
Core principle
Every function in cogpy should be:
Small: does one thing.
Pure: no hidden state, no side effects, no I/O.
Composable: inputs and outputs are standard types (numpy arrays, xarray DataArrays, pandas DataFrames).
Domain-agnostic: no function should “know” about specific hardware, experiments, or artifact types.
High-level orchestration — sequencing these primitives into a workflow for a specific dataset — belongs outside cogpy, in Snakemake pipelines, notebooks, or project-specific code.
Quick-reference imports
Grouped by task. All paths below use the shortest public route.
# --- Event detection & matching ---
from cogpy.detect import ThresholdDetector, BurstDetector
from cogpy.detect.utils import score_to_bouts, merge_intervals
from cogpy.events import EventCatalog
from cogpy.events.match import (
match_nearest, match_nearest_symmetric,
estimate_lag, estimate_drift, event_lag_histogram,
)
# --- Triggered analysis & templates ---
from cogpy.brainstates.intervals import perievent_epochs
from cogpy.triggered import (
triggered_average, triggered_std, triggered_median, triggered_snr,
estimate_template, fit_scaling, subtract_template,
)
# --- Regression ---
from cogpy.regression import (
lagged_design_matrix, event_design_matrix,
ols_fit, ols_predict, ols_residual,
)
# --- Spectral ---
from cogpy.spectral.psd import psd_welch, psd_multitaper
from cogpy.spectral.specx import spectrogramx, psdx
from cogpy.spectral.features import (
band_power, relative_band_power, spectral_peak_freqs,
ftest_line_scan, line_noise_ratio, narrowband_ratio,
am_artifact_score, am_depth,
)
from cogpy.spectral.bivariate import coherence, plv, cross_spectrum
# --- Spatial measures & filtering ---
from cogpy.measures.spatial import (
moran_i, gradient_anisotropy, spatial_kurtosis,
marginal_energy_outlier, csd_power, spatial_coherence_profile,
)
from cogpy.preprocess.filtering.spatial import (
gaussian_spatialx, median_spatialx, median_subtractx,
)
from cogpy.preprocess.filtering.reference import cmrx
# --- Decomposition ---
from cogpy.decomposition.pca import erpPCA
# --- Validation metrics ---
from cogpy.measures.comparison import (
snr_improvement, residual_energy_ratio,
bandpower_change, waveform_residual_rms,
)
Capability areas
cogpy organizes its primitives into the following capability areas. Each table lists the function, its import module, signature sketch, and purpose.
Events
Detect, refine, and relate discrete events in signals.
Primitive |
Import from |
Signature |
Purpose |
|---|---|---|---|
|
|
|
Threshold-crossing detection |
|
|
|
Spectral peak (h-maxima) detection |
|
|
|
Score → interval events via dual threshold |
|
|
|
Merge adjacent intervals |
|
|
container (DataFrame-backed) |
Unified event container with filter/query methods |
|
|
|
Find overlapping intervals |
|
|
|
Nearest-neighbor event matching (greedy) |
|
|
|
Bijective 1:1 event matching |
|
|
|
Cross-correlogram between event trains |
|
|
|
Constant lag estimate (median/mean/mode) |
|
|
|
Polynomial drift coefficients |
Triggered analysis
Extract and summarize signal epochs aligned to events.
Primitive |
Import from |
Signature |
Purpose |
|---|---|---|---|
|
|
|
Extract time-locked windows |
|
|
|
Mean across epochs |
|
|
|
Robust median across epochs |
|
|
|
Variability across epochs |
|
|
|
Consistency of event-locked response |
|
|
|
Template from epoch stack (mean/median/trimmean) |
|
|
|
Per-event amplitude via dot-product projection |
|
|
|
Remove scaled template at event locations |
Regression
Linear model building blocks for component removal.
Primitive |
Import from |
Signature |
Purpose |
|---|---|---|---|
|
|
|
Toeplitz matrix from reference signal |
|
|
|
Place template at event times |
|
|
|
Least-squares coefficient estimation |
|
|
|
Predicted signal from design + coefficients |
|
|
|
|
Spectral
Frequency-domain analysis.
Primitive |
Import from |
Signature |
Purpose |
|---|---|---|---|
|
|
|
Welch PSD estimate |
|
|
|
Multitaper PSD estimate |
|
|
|
xarray PSD wrapper |
|
|
|
xarray multitaper spectrogram |
|
|
|
Integrate PSD over band (trapezoid) |
|
|
|
Normalized band power ratio |
|
|
|
Find spectral peaks (Hz) |
|
|
|
F-test for sinusoidal lines |
|
|
|
Narrowband contamination at f_line |
|
|
|
Per-bin peak-to-background ratio |
|
|
|
Amplitude-modulation sideband score |
|
|
|
Magnitude squared coherence |
|
|
|
Phase locking value |
|
|
|
Cross-spectral density |
Spatial
Grid-electrode spatial analysis and filtering.
Primitive |
Import from |
Signature |
Purpose |
|---|---|---|---|
|
|
|
Spatial autocorrelation (queen/rook/directional) |
|
|
|
log₂ ratio of AP vs ML gradients |
|
|
|
Excess kurtosis of spatial amplitude distribution |
|
|
|
Fraction of energy in top-k electrodes |
|
|
|
Row/column energy outlier scores |
|
|
|
Current source density via 2D Laplacian |
|
|
|
Coherence vs inter-electrode distance |
|
|
|
Common median reference |
|
|
|
Spatial Gaussian lowpass |
|
|
|
Spatial median lowpass |
|
|
|
Spatial median reference |
|
|
|
Varimax-rotated PCA estimator |
Validation
Before/after comparison metrics.
Primitive |
Import from |
Signature |
Purpose |
|---|---|---|---|
|
|
|
Change in SNR (dB) |
|
|
|
Energy fraction remaining |
|
|
|
Fractional change in band power |
|
|
|
Template waveform difference |
How primitives compose
Primitives are designed to be chained in arbitrary order by the caller. Here are conceptual composition patterns (pseudo-code, not runnable pipelines):
Pattern: event-triggered template removal
from cogpy.detect import ThresholdDetector
from cogpy.events.match import match_nearest
from cogpy.brainstates.intervals import perievent_epochs
from cogpy.triggered import estimate_template, fit_scaling, subtract_template
from cogpy.spectral.psd import psd_multitaper
from cogpy.measures.comparison import bandpower_change
# 1. Detect events in a reference signal
detector = ThresholdDetector(threshold=3.0, direction="positive")
catalog = detector.detect(reference_signal)
event_times = catalog.df["t"].values
# 2. Match events to another stream
idx_a, idx_b, lags = match_nearest(events_a, events_b, max_lag=0.01)
# 3. Extract epochs around events
epochs = perievent_epochs(signal, event_times, fs, pre=0.01, post=0.01)
# 4. Estimate and subtract template
template = estimate_template(epochs, method="median")
alpha = fit_scaling(epochs.values, template.values)
cleaned = subtract_template(signal, event_samples, template.values, scaling=alpha)
# 5. Validate
psd_before, freqs = psd_multitaper(signal.values, fs)
psd_after, _ = psd_multitaper(cleaned.values, fs)
delta = bandpower_change(psd_before, psd_after, freqs, band=(100, 140))
Pattern: regression-based component removal
from cogpy.regression import lagged_design_matrix, ols_fit, ols_residual
# 1. Build lagged design matrix from reference
X = lagged_design_matrix(reference, lags=range(0, 20))
# 2. Fit and subtract per channel
beta = ols_fit(X, multichannel_signal)
cleaned = ols_residual(X, multichannel_signal, beta)
Pattern: spatial characterization
from cogpy.brainstates.intervals import perievent_epochs
from cogpy.triggered import triggered_average
from cogpy.measures.spatial import gradient_anisotropy, moran_i
# Compute spatial structure of an event-locked map
epochs = perievent_epochs(grid_signal, event_times, fs, pre=0.005, post=0.005)
avg_map = triggered_average(epochs)
aniso = gradient_anisotropy(avg_map)
moran = moran_i(avg_map, adjacency="queen")
Pattern: spectral artifact diagnostics
from cogpy.spectral.psd import psd_multitaper
from cogpy.spectral.features import ftest_line_scan, narrowband_ratio, am_artifact_score
# 1. Scan for sinusoidal lines
fstat, freqs, sig_mask = ftest_line_scan(signal, fs, NW=4.0)
# 2. Per-bin peak-to-background ratio
ratio = narrowband_ratio(psd, freqs, flank_hz=5.0)
# 3. Amplitude modulation sidebands
score = am_artifact_score(psd, freqs, fc=120.0, fm=60.0)
Each step is independent and reusable. The composition lives outside cogpy.