Tensor-field workflows¶
jaxfne organizes neural model outputs into a source-to-field/readout pipeline:
Emitter/Network → Source tensors → Field operators → Probe readouts → Output bundles
Pipeline overview¶
1. Emitter outputs¶
Start with spike or voltage outputs from:
- jaxfne Izhikevich emitters
- Jaxley-style neuron/network models
- Custom JAX arrays (organized as [time, neurons] or [time, neurons, features])
2. Source tensors¶
Organize emitter outputs into spatially localized currents:
- Source projection: Map emitter states to physical/proxy current
- Spatial support: Declare layer/depth assignments for field-proxy operator placement (not PDE solvers in v0.3.x)
- Metadata: Track source origin (emitter type, calibration status)
3. Field operators¶
Compute extracellular potentials and derived quantities:
- LFP-proxy: Average extracellular potential at contact depths
- CSD-proxy: Current-source density (second spatial derivative)
- Geometry: Laminar contact depths or custom field geometry
4. Probe readouts¶
Extract multimodal outputs:
- SPK: Spike times or spike matrix
- Vm: Membrane voltage or emitter state
- Source: Source tensor (projection or base)
- LFP-proxy, CSD-proxy: Field quantities
- EEG-proxy, MEG-proxy: Linear projections (toy or declared)
- EMM-proxy: Normalized activity cost
5. Output bundles¶
Serialize workflows as JSON-safe manifests:
- Data arrays: Readouts, signals, field outputs
- Metadata: Operator status, units, assumptions, status
- Receipts: Run ID, seed, execution time, validation flags
- Validation: JSON encoding enforces strict serialization (no NaN/Inf by default)
Example: Single neuron multimodal¶
import jaxfne as jtfne
# Configure
cfg = (
jtfne.configuration()
.network(n=1)
.emitter(family="izhikevich")
.field(domain="point")
.probe(name="single_neuron", modes=["spikes", "V_m", "source"])
)
# Build
model = jtfne.construct(cfg)
# Simulate
signals = model.simulate(jtfne.simulation(duration_ms=100.0, dt_ms=0.1))
# Readouts
readouts = model.compute_readout(signals, [
jtfne.readout_spec("spike_count", "spike_count"),
jtfne.readout_spec("voltage_mean", "voltage_mean"),
])
# Manifest
manifest = model.manifest(signals, readouts)
Mathematical notation¶
The source-to-field-to-probe pipeline uses standardized operator notation:
Source tensor construction¶
Source tensor from emitter: \(T\) time steps, \(N\) neurons, optional \(L\) layers/depths.
Source-to-field proxy projection¶
Potential at contact \(c\) via row-normalized kernel \(W\):
No PDE solve; purely declarative projection matrix.
Row-normalized Gaussian kernel (example)¶
Kernel centered at contact depth \(z_c\), localized by \(\sigma\). Normalization enforces row sum = 1.
Field-to-probe readout (generic operator form)¶
Generic probe operator \(\mathcal{O}_j\) applies to field potential, source, or both.
JSON-safe report sidecar¶
Report declares solver path (proxy vs. physical), convergence status, and statement constraints.
Field/proxy diagnostics (v0.2.6+)¶
jaxfne distinguishes between proxy readout paths and physical solver paths using field diagnostics:
Proxy readout path (v0.2.3–present)¶
Laminar proxy operators project source tensors directly to contacts without solving a PDE:
- Source-balance: Not applicable (no PDE solve)
- Gauge: Declared metadata only
- Boundary condition: Declared metadata only
- Physical amplitude statuss: False by default
Physical solver path¶
Future versions will support full PDE solvers with these diagnostics:
- Source-balance: Integrated source vs boundary flux residual
- Gauge: Mean-zero residual checking
- Boundary condition: Flux residual validation
- Manufactured residual: PDE solver convergence metric
Using diagnostics¶
from jaxfne.validation import (
make_field_operator_status,
make_source_balance_diagnostic,
make_gauge_diagnostic,
)
# Declare proxy path
operator = make_field_operator_status(operator_path="proxy")
# → field_solver_status: "linear_solver"
# Declare physical_candidate path
operator = make_field_operator_status(operator_path="physical_candidate")
# → field_solver_status: "physical_field_solver_candidate"
All diagnostics keep amplitude_status: false in v0.2.6. Physical amplitude statuss require separate calibration and validation evidence.
Local and global summaries¶
For circuit-level workflows, tensor-field operations can produce:
- Local summaries: Per-layer or per-region spike rates, LFP power
- Global summaries: Whole-network activity, cross-layer synchronization
- Traveling-wave summaries: (Reserved) Spatiotemporal dynamics across layers/regions
See tutorials for examples.
Next steps¶
- Tutorials for progressively detailed workflows
- Calibration for preparing outputs for empirical validation
- Jaxley interoperability for using Jaxley models as sources