v0.3.6: 100-Neuron Excitatory-Inhibitory Population¶
Duration: 15–20 minutes | Difficulty: Intermediate | jaxfne 0.3.42
Overview¶
This tutorial demonstrates the chainable Configuration API of jaxfne (introduced in v0.3.5, current in jaxfne==0.3.42), built for streamlined workflow composition. You will build, simulate, and analyze a 100-neuron excitatory-inhibitory (E/I) population using the new fluent configuration grammar.
What You'll Learn¶
- Use the chainable
ConfigurationAPI (runtime(),column(),cell_types(),connectivity(),set_emitter(),probes()) - Configure a biologically-inspired E/I population (75% excitatory, 25% inhibitory)
- Simulate with the Izhikevich neuron model (cortical parameters)
- Extract multimodal readouts: spikes, voltage, source, and field proxies
- Inspect scope metadata to understand computational statements and scope notes
- Generate population-level metrics and visualizations
Key Concepts¶
Balanced Networks: Cortical populations are typically ~80% excitatory and ~20% inhibitory. This balance allows excitation and inhibition to approximately match, a principle central to cortical computation.
Chainable API: The new Configuration class uses method chaining to compose models fluently:
cfg = (jtfne.Configuration()
.runtime(seed=42, duration_ms=1000.0, dt_ms=0.1)
.column(name="L2/3_column", layers=["L2/3"], n=100)
.cell_types({"E": 0.75, "I": 0.25})
.connectivity()
.set_emitter(family="izhikevich", preset="cortical_eig")
.probes(["SPK", "Vm", "source", "LFP-proxy", "CSD-proxy"]))
Proxy-Scale Readouts: Field outputs (LFP, CSD) are computed via convolution-based proxies, not full PDE solutions. This enables fast visualization and relative comparison without stating physical amplitude.
Tutorial Workflow¶
The notebook follows a 13-section structure:
- Learning Objectives — Expected outcomes
- Biological Question — The E/I coupling problem
- Mathematical Glossary — Izhikevich equations and metrics
- Canonical Import —
import jaxfne as jtfne - Configuration Block — Chainable API setup
- Simulation Block — Construct model and run
- Probe/Readout Block — Compute population metrics
- Manifest and Scope Metadata — JSON output with scope statements
- Figures — Five visualizations (raster, rates, voltages, source, summary)
- Interpretation — Results and dynamics
- Failure Modes — Debugging silent or unstable networks
- Exercises — Extensions (vary E/I ratio, try presets, etc.)
- Scope Boundaries — What this tutorial is and is not
Quick Reference¶
Configuration¶
cfg = jtfne.Configuration()
# Set runtime parameters
cfg = cfg.runtime(seed=42, dtype="float32", duration_ms=1000.0, dt_ms=0.1)
# Define cortical column: 100 neurons
cfg = cfg.column(name="L2/3_column", layers=["L2/3"], n=100)
# Excitatory-inhibitory composition
cfg = cfg.cell_types({"E": 0.75, "I": 0.25})
# All-to-all connectivity
cfg = cfg.connectivity()
# Izhikevich neuron with cortical parameters
cfg = cfg.set_emitter(family="izhikevich", preset="cortical_eig")
# Multimodal probes
cfg = cfg.probes(["SPK", "Vm", "source", "LFP-proxy", "CSD-proxy"])
Simulation and Readouts¶
model = jtfne.construct(cfg)
signals = jtfne.simulate(model, duration_ms=1000.0, dt_ms=0.1, seed=42)
# Compute population metrics
readout_specs = [
jtfne.readout_spec("population_rate", "spike_rate_hz"),
jtfne.readout_spec("mean_voltage", "mean_V_m"),
]
readouts = model.compute_readout(signals, readout_specs)
Expected Results¶
| Metric | Typical Value | Valid Range |
|---|---|---|
| Excitatory rate | 8–15 Hz | 2–25 Hz |
| Inhibitory rate | 8–15 Hz | 2–25 Hz |
| Population mean rate | 8–15 Hz | 2–25 Hz |
| Voltage min | ~-80 mV | -100 to -60 mV |
| Voltage max | ~30 mV | 20–40 mV |
| All outputs finite | True | — |
Scope notes and Extension Notess¶
✓ What This Tutorial Is¶
- A computational scaffold for learning E/I coupling principles
- A demonstration of the new chainable Configuration API
- A proxy-scale visualization and relative-comparison tool
- JAX-based, deterministic, and reproducible
✗ What This Tutorial Is NOT¶
- A biophysically realistic neuron model (Izhikevich is phenomenological)
- A validated field solver (LFP/CSD are proxy approximations, not PDE-solved)
- A tool for direct comparison with real recordings (uncalibrated)
- A framework for source localization (no inverse problem)
- A complete cortical circuit (missing plasticity, neuromodulation)
Scope Metadata¶
All outputs include manifest JSON with explicit scope statements:
{
"scope_status": "computational_scaffold",
"calibration_status": "uncalibrated_phenomenological",
"readout_status": "proxy_scale",
"field_mode": "proxy_convolution_no_pde",
"amplitude_status": false
}
Key principle: Proxy-scale outputs enable comparison and visualization without stating physical validity.
Running the Notebook¶
In Colab (Recommended)¶
Click the Open in Colab badge at the top. The notebook runs CPU-safe in ~2–3 minutes.
Locally¶
# Download and run
jupyter notebook tutorials/jaxfne_v036_100_neuron_ei_population.ipynb
# Or execute with nbconvert
jupyter nbconvert --execute tutorials/jaxfne_v036_100_neuron_ei_population.ipynb
Validation¶
# Run tests
JAXFNE_VALIDATE_TUTORIAL_OUTPUTS=1 pytest tests/test_v036_100_neuron_ei_population_tutorial.py -v
Next Steps¶
After this tutorial:
- Modify E/I ratios — Explore how balance affects stability
- Try emitter presets — "tonic_spiking", "phasic_spiking", "fast_spiking"
- Extend to multiple layers — Add L4 and L5 with inter-layer connections
- Calibrate to real data — Use guided exercises in Calibration guide
- Explore field relationships — See Tensor-Field Workflows
References¶
- Izhikevich neuron model: Izhikevich, E. M. (2003). Simple model of spiking neurons. IEEE Trans. Neural Netw., 14(6), 1569–1572.
- Balanced networks: van Vreeswijk, C., & Sompolinsky, H. (1996). Chaos in neuronal networks with balanced excitatory and inhibitory activity. Science, 274(5293), 1724–1726.
- jaxfne API: See Configuration, Runtime, Emitters, Probes
Troubleshooting¶
Silent network (< 1 Hz)?
Try a different seed, switch emitter preset to "tonic_spiking", or increase external input current.
Runaway network (> 50 Hz)?
Use a preset with stronger adaptation (e.g., "chattering") or increase inhibitory coupling strength.
NaN/Inf in output?
Reduce timestep to 0.01 ms, use float64 precision, or check Izhikevich parameter bounds.