sparx.graph
Circuits and connectomes: populations of neurons joined by projections, simulated on one clock.
sparx.dynamics holds the models of single neurons, synapses and
plasticity rules; this package wires them into networks (design.md
sections 5 and 6), builds the canonical ones and the published models on
connectomes, and simulates them over dew’s meshes and checkpoints.
The names here are the ones a model and a run are written with. The types
of the state, the layout rules and the connectome constants stay in their
modules (sparx.graph.network, sparx.graph.simulate,
sparx.graph.connectome).
Modules
Section titled “Modules”| Module | |
|---|---|
sparx.graph.simulate | Running a network for a long time: compiled chunks, state carried between them, records on the host. |
Contents
Section titled “Contents”| Name | |
|---|---|
AllToAll | Every presynaptic neuron to every postsynaptic one (without self-connections unless autapses). |
ArrivalInput | Weights arriving on receptor of target at the end of each step, from the drive passed under name ([T, size]): recorded spike trains replayed into a network, in the receptor’s unit. |
Connectome | Neurons ids (e.g. FlyWire root IDs) and edges pre -> post (indices) with signed synapse counts. |
CurrentInput | A current (pA) into target, from the drive passed to the network under name ([T, size] or [T] per step, or a constant). |
FixedInDegree | Each postsynaptic neuron receives exactly k inputs, drawn without replacement unless multapses. |
FixedOutDegree | Each presynaptic neuron projects to exactly k targets. NEST’s fixed_outdegree. |
FixedProbability | Each pair independently with probability p (Erdős-Rényi), NEST’s pairwise_bernoulli. |
FixedTotalNumber | Exactly n edges between the two populations, each pair drawn uniformly. NEST’s fixed_total_number. |
FromEdges | Given edges, as from a connectome table. Pairs may repeat (multapses). |
GapJunction | Electrical synapses between populations a and b, each passing I = g (v_partner - v). |
Modulator | A neuromodulator that the spikes of source release and volume transmission spreads, one concentration for the whole network. |
ModulatorTrace | The concentration of the modulator named modulator after each step. |
Monitor | Something recorded every step: record(outputs, states, dt, modulators) with outputs and states keyed by population, dt the step in ms, and the modulators’ concentrations by name. |
Network | Populations and projections stepped together; see the module docstring. |
OneToOne | Neuron i to neuron i; the populations must be the same size. |
OutputTrace | What population sends each step, for the neurons neurons (indices) or all of them: a graded population’s values (a release, an activity), or a spiking one’s spikes as 0 and 1. |
PoissonInput | count independent Poisson sources of rate Hz onto each neuron of target, through receptor. |
Population | size neurons of one model, with the synapses onto them by receptor name. |
PopulationRate | The rate of population in each step, in Hz: the fraction of its neurons that fired in the step, over the step’s length in seconds. |
Projection | Synapses from population pre onto receptor receptor of population post. |
Simulation | What simulate returns: each monitor’s records over the steps this call ran, on the host and under the monitor’s name, and the final variables. |
SpikeCounts | Each neuron’s spike count over the run, summed as it goes: rates of large populations. |
SpikeRaster | Which neurons of population fired, as booleans. |
SpikeTimes | The indices of up to capacity neurons of population that fired each step, padded with -1: a raster of a large population at the cost of capacity integers per step. |
StateMonitor | read(state) of population each step, for the neurons neurons (indices) or all of them. |
brunel | Brunel’s (J. Comput. Neurosci. 2000) sparse network of excitatory and inhibitory LIF neurons, model A. |
coba | Vogels and Abbott’s (2005) network with conductance-based synapses (Brette et al.’s COBA benchmark). |
cuba | Vogels and Abbott’s (2005) network with current-based synapses: Brette et al.’s (2007) CUBA benchmark. |
from_record | The network a {"class": builder, "fields": {...}} record names, built from its fields. |
matched_w_syn | Shiu et al.’s w_syn scaled so connectome’s median neuron gets the input FlyWire’s did. |
microcircuit | Potjans and Diesmann’s (Cereb. Cortex 2014) cortical microcircuit: 1 mm^2 of cortex, layers 2/3 to 6. |
shiu2024 | Shiu et al.’s (Nature 2024) leaky integrate-and-fire model of the whole fly brain. |
AllToAll
Section titled “AllToAll”class AllToAllsparx.graph.connectivity on GitHub
Every presynaptic neuron to every postsynaptic one (without self-connections unless autapses).
| Field | Type | Default |
|---|---|---|
autapses | bool | False |
AllToAll.edges
Section titled “AllToAll.edges”def edges(rng: np.random.Generator, pre: int, post: int, same: bool) -> EdgeListArrivalInput
Section titled “ArrivalInput”class ArrivalInputWeights arriving on receptor of target at the end of each step, from the drive passed under
name ([T, size]): recorded spike trains replayed into a network, in the receptor’s unit.
| Field | Type | Default |
|---|---|---|
target | str | |
name | str | |
receptor | str |
Connectome
Section titled “Connectome”class Connectomesparx.graph.connectome on GitHub
Neurons ids (e.g. FlyWire root IDs) and edges pre -> post (indices) with signed synapse counts.
| Field | Type | Default |
|---|---|---|
ids | np.ndarray | |
pre | np.ndarray | |
post | np.ndarray | |
synapses | np.ndarray | |
size | int |
Connectome.inputs
Section titled “Connectome.inputs”def inputs() -> np.ndarrayEach neuron’s input synapses, excitatory and inhibitory alike.
Connectome.index
Section titled “Connectome.index”def index(ids: Iterable[int]) -> np.ndarrayThe neuron indices of ids; raises for an ID not in the connectome.
Connectome.without
Section titled “Connectome.without”def without(silenced: Iterable[int]) -> ConnectomeThe connectome with every synapse from the neurons silenced (indices) removed.
Connectome.from_shiu
Section titled “Connectome.from_shiu”def from_shiu(completeness: str | Path, connectivity: str | Path) -> ConnectomeRead Shiu et al.’s (2024) tables (github.com/philshiu/Drosophila_brain_model).
completeness is the CSV of neurons, indexed by FlyWire root ID, whose
row order defines the neuron indices; connectivity the parquet file
of edges with Presynaptic_Index, Postsynaptic_Index and
Excitatory x Connectivity (the signed synapse count). Both FlyWire
v630, which their paper used, and the public v783 tables read alike.
Connectome.from_malecns
Section titled “Connectome.from_malecns”def from_malecns(annotations: str | Path, neurotransmitters: str | Path, weights: str | Path, statuses: Sequence[str] = ('Traced', 'Anchor'), signs: dict[str, int] | None = None) -> ConnectomeRead Janelia’s male CNS (brain and nerve cord) release tables, gs://flyem-male-cns/v0.9.
annotations (body-annotations-*.feather) lists the bodies; those
whose status is in statuses are the neurons (165,114 Traced
and 785 Anchor in v0.9, against 1.8M segments in all).
neurotransmitters (body-neurotransmitters-*.feather) gives each
body’s predicted transmitter, consensus_nt or, where that is
unclear, predicted_nt; signs maps it to the sign of the
neuron’s synapses. weights (connectome-weights-*.feather) holds
the synapse count of every connected pair of segments, filtered here
to pairs of neurons. Neurons are ordered by body ID.
CurrentInput
Section titled “CurrentInput”class CurrentInputA current (pA) into target, from the drive passed to the network under name ([T, size] or
[T] per step, or a constant).
| Field | Type | Default |
|---|---|---|
target | str | |
name | str |
FixedInDegree
Section titled “FixedInDegree”class FixedInDegreesparx.graph.connectivity on GitHub
Each postsynaptic neuron receives exactly k inputs, drawn without replacement unless multapses.
Brunel (2000) connects this way: every neuron receives C_E excitatory
and C_I inhibitory inputs. NEST’s fixed_indegree.
| Field | Type | Default |
|---|---|---|
k | int | |
autapses | bool | False |
multapses | bool | False |
FixedInDegree.edges
Section titled “FixedInDegree.edges”def edges(rng: np.random.Generator, pre: int, post: int, same: bool) -> EdgeListFixedOutDegree
Section titled “FixedOutDegree”class FixedOutDegreesparx.graph.connectivity on GitHub
Each presynaptic neuron projects to exactly k targets. NEST’s fixed_outdegree.
| Field | Type | Default |
|---|---|---|
k | int | |
autapses | bool | False |
multapses | bool | False |
FixedOutDegree.edges
Section titled “FixedOutDegree.edges”def edges(rng: np.random.Generator, pre: int, post: int, same: bool) -> EdgeListFixedProbability
Section titled “FixedProbability”class FixedProbabilitysparx.graph.connectivity on GitHub
Each pair independently with probability p (Erdős-Rényi), NEST’s pairwise_bernoulli.
| Field | Type | Default |
|---|---|---|
p | float | |
autapses | bool | False |
FixedProbability.edges
Section titled “FixedProbability.edges”def edges(rng: np.random.Generator, pre: int, post: int, same: bool) -> EdgeListFixedTotalNumber
Section titled “FixedTotalNumber”class FixedTotalNumbersparx.graph.connectivity on GitHub
Exactly n edges between the two populations, each pair drawn uniformly. NEST’s fixed_total_number.
Potjans and Diesmann’s (2014) cortical microcircuit connects this way,
with n set so that a pair is connected at least once with the
measured probability. With multapses each edge draws its pair
independently, so a pair may repeat; without, n distinct pairs.
| Field | Type | Default |
|---|---|---|
n | int | |
autapses | bool | False |
multapses | bool | False |
FixedTotalNumber.edges
Section titled “FixedTotalNumber.edges”def edges(rng: np.random.Generator, pre: int, post: int, same: bool) -> EdgeListFromEdges
Section titled “FromEdges”class FromEdgessparx.graph.connectivity on GitHub
Given edges, as from a connectome table. Pairs may repeat (multapses).
| Field | Type | Default |
|---|---|---|
pre | np.ndarray | |
post | np.ndarray |
FromEdges.edges
Section titled “FromEdges.edges”def edges(rng: np.random.Generator, pre: int, post: int, same: bool) -> EdgeListGapJunction
Section titled “GapJunction”class GapJunctionElectrical synapses between populations a and b, each passing I = g (v_partner - v).
Each edge of connectivity (from a neuron of a to one of b) is one
junction of conductance weight (nS), symmetric: the current into the
neuron of a is g (v_b - v_a), and the current into the neuron of b
is its negative. a and b may be one population. Both need a membrane
voltage v in mV, as the physical models have.
The coupling has no delay, and each step solves it in two passes. Every
coupled population first advances with its partners’ voltages held at
their values at the start of the step, which predicts their voltages
at its end. It then advances again from the start, with each partner’s
voltage moving linearly from its start to its predicted end. A neuron
integrates the coupling against its own voltage as a conductance, and
its partners’ side as a current waveform (sparx.dynamics.Gap), which
a linear membrane solves exactly and stably. The result is second order
in dt. This is one iteration of the waveform relaxation NEST uses
(Hahne et al., Frontiers in Neuroinformatics 2015), which iterates
until the interpolated voltages agree to a tolerance and so converges
to the coupled solution; without it NEST holds each partner at its
voltage of the step before. tests/test_signalling.py compares sparx
with the analytic solution of two coupled passive cells and with NEST.
Coupled populations advance twice per step; the others once.
| Field | Type | Default |
|---|---|---|
a | str | |
b | str | |
connectivity | Connectivity | |
weight | PerEdge | 1.0 |
name | str | None | None |
key | str |
Modulator
Section titled “Modulator”class ModulatorA neuromodulator that the spikes of source release and volume transmission spreads, one
concentration for the whole network.
dc/dt = -c / tau + release * sum_k delta(t - t_k)over the spikes t_k of source’s neurons, or of the neurons
neurons (indices) when given, such as the dopaminergic neurons of a
connectome. Each spike adds release to the concentration, which decays
with tau (ms) between spikes, exactly on the step grid. The
concentration is in the network’s state (NetworkState["modulators"],
by name), and each Plasticity rule reads it every step as a third
factor.
| Field | Type | Default |
|---|---|---|
name | str | |
source | str | |
tau | float | |
release | float | 1.0 |
neurons | tuple[int, ...] | None | None |
ModulatorTrace
Section titled “ModulatorTrace”class ModulatorTrace(Monitor)The concentration of the modulator named modulator after each step.
| Field | Type | Default |
|---|---|---|
modulator | str |
ModulatorTrace.record
Section titled “ModulatorTrace.record”def record(outputs, states, dt, modulators)Monitor
Section titled “Monitor”class MonitorSomething recorded every step: record(outputs, states, dt, modulators) with outputs and states
keyed by population, dt the step in ms, and the modulators’ concentrations by name.
A record is one array per step, stacked over the run into [T, ...].
A monitor with accumulate = True is summed over the steps of a run
instead of stacked, so its memory does not grow with the run. Monitors
are passed by name (monitors={"rate": PopulationRate("e")}), and the
records come back under the same names.
| Field | Type | Default |
|---|---|---|
accumulate | bool | False |
Monitor.record
Section titled “Monitor.record”def record(outputs: Mapping[str, jax.Array], states: Mapping[str, PointNeuronState], dt: float, modulators: Mapping[str, jax.Array]) -> jax.ArrayNetwork
Section titled “Network”class Network(nn.Module)Populations and projections stepped together; see the module docstring.
| Field | Type | Default |
|---|---|---|
populations | Sequence[Population] | |
projections | Sequence[Projection] | () |
inputs | Sequence[PoissonInput | CurrentInput | ArrivalInput] | () |
dt | float | 0.1 |
dtype | jax.typing.DTypeLike | jnp.float32 |
junctions | Sequence[GapJunction] | () |
modulators | Sequence[Modulator] | () |
Network.connections
Section titled “Network.connections”def connections(variables: Variables) -> dict[str, Connections]Every projection’s synapses after a run, by projection key, as NEST’s GetConnections reads them.
pre, post, weight, delay = network.connections(result.variables)["e->e:ampa"]Weights come from where the projection keeps them: the state for a
plastic one (as learned so far), params for a trainable one, the
connectome otherwise. A dense projection stores a matrix and no edge
list, so its connections are the matrix’s nonzero entries, with
repeated pairs summed.
Network.__call__
Section titled “Network.__call__”def __call__(drive: Drive | None = None, steps: int | None = None, monitors: Mapping[str, Monitor] | None = None) -> dict[str, jax.Array]Advance steps steps (or as many as drive has); returns each monitor’s records over time, under
the monitor’s name.
OneToOne
Section titled “OneToOne”class OneToOnesparx.graph.connectivity on GitHub
Neuron i to neuron i; the populations must be the same size.
OneToOne.edges
Section titled “OneToOne.edges”def edges(rng: np.random.Generator, pre: int, post: int, same: bool) -> EdgeListOutputTrace
Section titled “OutputTrace”class OutputTrace(Monitor)What population sends each step, for the neurons neurons (indices) or all of them: a graded
population’s values (a release, an activity), or a spiking one’s spikes as 0 and 1.
| Field | Type | Default |
|---|---|---|
population | str | |
neurons | tuple[int, ...] | None | None |
OutputTrace.record
Section titled “OutputTrace.record”def record(outputs, states, dt, modulators)PoissonInput
Section titled “PoissonInput”class PoissonInputcount independent Poisson sources of rate Hz onto each neuron of target, through receptor.
Brunel’s (2000) external drive: their sum is one Poisson process of
count * rate Hz, sampled per neuron and step. neurons limits the
input to those indices of target, as an optogenetic stimulus does.
| Field | Type | Default |
|---|---|---|
target | str | |
rate | float | |
weight | float | |
receptor | str | |
count | int | 1 |
neurons | tuple[int, ...] | None | None |
Population
Section titled “Population”class Populationsize neurons of one model, with the synapses onto them by receptor name.
neuron is any neuron model of sparx.dynamics, physical or
dimensionless; a dimensionless one (ALIFCell, say) takes its input
through delta receptors, as voltage jumps. A conductance receptor is
named for a reversal potential of the neuron model (LIF’s defaults are
ampa, nmda, gaba_a and gaba_b).
initial sets where each neuron starts, by name: a field of the neuron
model’s state ("v") or a receptor, whose synapse state it sets, each
to one value for all, an array [size] or f(rng, size) drawn from a
NumPy generator seeded by the network’s key. Everything else starts at
rest. reset_synapses and freeze_synapses are PointNeuron’s options.
| Field | Type | Default |
|---|---|---|
name | str | |
size | int | |
neuron | NeuronModel | |
receptors | Mapping[str, Receptor] | field(default_factory=dict) |
hold | Literal['mean', 'start'] | 'mean' |
initial | Mapping[str, PerNeuron] | field(default_factory=dict) |
reset_synapses | bool | False |
freeze_synapses | bool | False |
point_neuron | PointNeuron | |
graded | bool |
PopulationRate
Section titled “PopulationRate”class PopulationRate(Monitor)The rate of population in each step, in Hz: the fraction of its neurons that fired in the step,
over the step’s length in seconds.
Hz is the unit of PoissonInput.rate and sparx.spiketrains.rates_hz,
so a rate read here compares with them without conversion.
| Field | Type | Default |
|---|---|---|
population | str |
PopulationRate.record
Section titled “PopulationRate.record”def record(outputs, states, dt, modulators)Projection
Section titled “Projection”class ProjectionSynapses from population pre onto receptor receptor of population post.
receptor has no default: it sets the unit of weight (pA, nS or mV)
and, through the reversal potential, the sign of a conductance, so a
weight means nothing without it. delay is in ms and must be a whole
number of steps (whole_steps); either may be per edge. plasticity
(a Plasticity rule, pair or triplet STDP) makes the weights state that
evolves with the spikes; short_term scales each spike by its
presynaptic neuron’s release; release makes each edge transmit a spike
only with a probability, drawn from the network’s noise key.
trainable puts fixed weights in params for gradient training. A
projection from a graded population transmits weight times the
presynaptic value every step, and takes none of the spike-driven
options.
| Field | Type | Default |
|---|---|---|
pre | str | |
post | str | |
connectivity | Connectivity | |
weight | PerEdge | 1.0 |
delay | PerEdge | 1.0 |
receptor | str | field(kw_only=True) |
plasticity | Plasticity | None | None |
short_term | TsodyksMarkram | None | None |
release | StochasticRelease | None | None |
trainable | bool | False |
name | str | None | None |
format | Literal['auto', 'edges', 'dense', 'events'] | 'auto' |
per_pass | int | 16 |
key | str |
Simulation
Section titled “Simulation”class Simulationsparx.graph.simulate on GitHub
What simulate returns: each monitor’s records over the steps this call ran, on the host and under
the monitor’s name, and the final variables.
| Field | Type | Default |
|---|---|---|
records | dict[str, np.ndarray] | |
variables | Variables | |
dt | float | |
steps | int | |
start | float | 0.0 |
times | np.ndarray |
SpikeCounts
Section titled “SpikeCounts”class SpikeCounts(Monitor)Each neuron’s spike count over the run, summed as it goes: rates of large populations.
| Field | Type | Default |
|---|---|---|
population | str |
SpikeCounts.record
Section titled “SpikeCounts.record”def record(outputs, states, dt, modulators)SpikeRaster
Section titled “SpikeRaster”class SpikeRaster(Monitor)Which neurons of population fired, as booleans.
| Field | Type | Default |
|---|---|---|
population | str |
SpikeRaster.record
Section titled “SpikeRaster.record”def record(outputs, states, dt, modulators)SpikeTimes
Section titled “SpikeTimes”class SpikeTimes(Monitor)The indices of up to capacity neurons of population that fired each step, padded with -1:
a raster of a large population at the cost of capacity integers per step.
| Field | Type | Default |
|---|---|---|
population | str | |
capacity | int | 64 |
SpikeTimes.record
Section titled “SpikeTimes.record”def record(outputs, states, dt, modulators)StateMonitor
Section titled “StateMonitor”class StateMonitor(Monitor)read(state) of population each step, for the neurons neurons (indices) or all of them.
read takes the population’s PointNeuronState and returns one value
per neuron; it defaults to the membrane voltage. A voltage trace of
every neuron costs steps * size values, 32 MB for 800 neurons over
1 s at 0.1 ms, so neurons keeps the few a figure shows.
| Field | Type | Default |
|---|---|---|
population | str | |
read | Callable[[PointNeuronState], jax.Array] | _membrane |
neurons | tuple[int, ...] | None | None |
StateMonitor.record
Section titled “StateMonitor.record”def record(outputs, states, dt, modulators)brunel
Section titled “brunel”def brunel(order: int = 2500, g: float = 5.0, eta: float = 2.0, j: float = 0.1, delay: float = 1.5, epsilon: float = 0.1, dt: float = 0.1) -> NetworkBrunel’s (J. Comput. Neurosci. 2000) sparse network of excitatory and inhibitory LIF neurons, model A.
4 order excitatory and order inhibitory neurons (order=2500 is
the paper’s 12,500); each receives epsilon of each population’s
neurons, with delta synapses of j mV (excitatory) and -g j
(inhibitory), all after delay ms, and Poisson input from C_E
external neurons at eta times the rate that brings a free membrane to
threshold. Membranes: 20 ms, threshold 20 mV, reset 10 mV, 2 ms
refractory, rest 0. The regimes of his Figure 8: g=3, eta=2
synchronous regular; g=5, eta=2 asynchronous irregular; g=6, eta=4
synchronous irregular, fast; g=4.5, eta=0.9 synchronous irregular,
slow. These are the parameters of NEST’s brunel_delta_nest.py, and
as there inputs are drawn with replacement, self-connections allowed
(NEST’s fixed_indegree defaults).
def coba(dt: float = 0.1) -> NetworkVogels and Abbott’s (2005) network with conductance-based synapses (Brette et al.’s COBA benchmark).
The CUBA network’s structure with conductances of 6 and 67 nS, decaying
in 5 and 10 ms, reversing at 0 and -80 mV, on membranes of 200 pF and
10 nS resting at -60 mV (the reversal potentials are LeakyIntegrateAndFire’s defaults for
ampa and gaba_a). Activity is sustained from random initial
voltages and conductances (excitatory N(40, 15) nS, inhibitory
N(200, 120) nS), as Brian’s example sets them.
def cuba(dt: float = 0.1) -> NetworkVogels and Abbott’s (2005) network with current-based synapses: Brette et al.’s (2007) CUBA benchmark.
As Brian2’s examples/CUBA.py: 3,200 excitatory and 800 inhibitory
neurons connected with probability 0.02, without delay; membranes of
20 ms resting at -49 mV, above the -50 mV threshold, reset to -60 mV,
5 ms refractory; exponential currents of 5 and 10 ms. Brian2 states
the synapses in volts, 1.62 and -9 mV over the membrane time constant;
on a 200 pF membrane they are 16.2 and -90 pA. Voltages start uniform
between reset and threshold.
from_record
Section titled “from_record”def from_record(record: Record) -> NetworkThe network a {"class": builder, "fields": {...}} record names, built from its fields.
The builder is a short name of sparx.registry.networks or an import
path. A field that is itself a record names its class or function by
import path and is built first, so a model on a connectome is configured
by its reader and paths: {"class": "shiu2024", "fields": {"connectome": {"class": "sparx.graph.connectome:Connectome.from_shiu", "fields": {"completeness": ..., "connectivity": ...}}, "stimuli": ...}}.
matched_w_syn
Section titled “matched_w_syn”def matched_w_syn(connectome: Connectome, w_syn: float = 0.275, reference: float = FLYWIRE_630_MEDIAN_INPUTS) -> floatsparx.graph.connectome on GitHub
Shiu et al.’s w_syn scaled so connectome’s median neuron gets the input FlyWire’s did.
w_syn was fit to FlyWire v630’s synapse counts, and a connectome that
counts more synapses per neuron drives every neuron harder at the same
weight. The male CNS v0.9 counts a median 347 input synapses per neuron
against FlyWire’s 206 (its mean, 748 against 414, grows alike), so it
takes 0.163 mV: with 0.275 mV its sugar neurons recruit 18,000 neurons,
with 0.163 mV about 670 (FlyWire: about 400), and MN9 fires as Shiu et
al.’s does (docs/fidelity.md).
microcircuit
Section titled “microcircuit”def microcircuit(neurons: float = 1.0, indegrees: float = 1.0, background: Literal['dc', 'poisson'] = 'dc', dt: float = 0.1) -> NetworkPotjans and Diesmann’s (Cereb. Cortex 2014) cortical microcircuit: 1 mm^2 of cortex, layers 2/3 to 6.
Eight populations, an excitatory and an inhibitory one per layer, of
iaf_psc_exp neurons (10 ms, 250 pF, rest and reset -65 mV, threshold
-50 mV, 2 ms refractory, 0.5 ms currents), 77,169 at full scale. Each
pair of populations is joined by a fixed total number of synapses,
drawn with replacement, self-connections allowed, set so that a pair of
neurons is connected at least once with the measured probability.
Weights are normal around a current that peaks at 0.15 mV (twice that
from L4E to L2/3E, -4 times it from inhibitory neurons), 10% standard
deviation, drawn again where they change sign; delays are normal around
1.5 ms (excitatory) and 0.75 ms (inhibitory), 50% standard deviation,
drawn again below half a step and rounded to steps, as NEST rounds them.
The cortico-cortical input is a constant current per population
(background="dc", the reference’s default) or Poisson spikes at 8 Hz
from each of its inputs. A population fires at a few Hz, so a step’s
events from one population are few, and each projection delivers them
in passes of 4: at a fifth, 8.8 s per simulated second on a 4-core CPU,
against 9.7 s for passes of 2, 9.9 s for 8 and 12.8 s for 16
(benchmarks/bench_networks.py).
neurons scales the population sizes and indegrees the inputs per
neuron. With fewer inputs, each weight grows by one over the square
root of the scale and a current makes up the mean input lost at the
full model’s rates, which keeps each population’s rate. At a fifth of
both (microcircuit(0.2, 0.2): 15,435 neurons, 12 million synapses)
the populations fire as in the full model; at a tenth, the currents
leave all but L6I below threshold and the network falls silent, in NEST
as here. Every number is from the PyNEST implementation of
INM-6/microcircuit-PD14-model (commit f79f8ac), which
tests/test_microcircuit.py compares against.
shiu2024
Section titled “shiu2024”def shiu2024(connectome: Connectome, stimuli: Sequence[tuple[Sequence[int], float]] = (), silenced: Sequence[int] = (), dt: float = 0.1, w_syn: float = 0.275, stimulus_scale: float = 250.0) -> Networksparx.graph.connectome on GitHub
Shiu et al.’s (Nature 2024) leaky integrate-and-fire model of the whole fly brain.
Every neuron is one LIF: membrane 20 ms, rest and reset -52 mV,
threshold -45 mV, 2.2 ms refractory, driven by
dv/dt = (v_0 - v + g) / tau_m with dg/dt = -g / tau, tau = 5 ms.
A spike adds w_syn (0.275 mV) times the signed synapse count to the
target’s g after 1.8 ms. stimuli are (neuron indices, rate in Hz):
each neuron gets Poisson spikes at the rate that move its voltage by
stimulus_scale * w_syn (enough to fire it) and has no refractory
period, their model of optogenetic activation. silenced neurons
(indices) lose their outgoing synapses. On a connectome other than
FlyWire v630, matched_w_syn scales w_syn to its synapse counts.
The model is theirs as their Brian2 code runs it (model.py, checked
spike for spike on a small graph in tests/test_graph.py), quirks
included: a spike also clears g, g holds while refractory and drops
input arriving then, and a stimulus lands after the threshold test.
Brian2 counts the refractory period from the start of the spiking step,
so its 2.2 ms is sparx’s 2.1 (21 steps of 0.1 ms).