You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While working on the baseexport module I noticed that the serialization pipeline is entirely one-way. The exporter device produces a structured Python dictionary of a Brian2 network, but there is nothing on the other side that can consume it and reconstruct a runnable Network object. I'd like to propose and implement a basicimporter module that closes this gap and makes round-trip serialization possible for the first time.
This is a significant missing piece a researcher who exports their network architecture today has no programmatic way to reload it. They would have to manually re-write the Brian2 code from scratch using the exported dictionary as a reference, which defeats the purpose of having a structured export format at all.
exported = device.runs # this is where it ends nothing can consume this device.runs contains a complete structured representation of the network equations, parameters, connectivity rules, initializers, monitor configurations but there is no import_network(exported) call that can turn it back into a runnable Brian2 network. The data is there, the consumer is not.
What the Current Exporter Is Still Missing
Before a correct importer can be written, I found a few gaps in the exporter that need to be addressed first:
Custom function bodies not serialized In _prepare_identifiers (helper.py), custom Function objects only have their metadata captured (arg units, return unit) not the implementation. If an equation references a custom function, the importer has no way to reconstruct it. Serializing inspect.getsource(value.pyfunc) when available would fix this. I plan to raise this as a separate issue.
Equations dict → string reconstruction
The exporter stores equations as a parsed dictionary (per-variable type, unit, expr, flags). To pass them back into NeuronGroup(model=...), we need
a helper that reconstructs a valid Brian2 equation string from that dict. That direction is currently missing and will need to be part of the importer itself.
NetworkOperation function bodies I added metadata capture for NetworkOperation (name, dt, when, order) in PR Fix baseexport: serialize hetero delays, capture resolved integrator, handle NetworkOperation #76, but the function body itself cannot be serialized automatically. This is a known limitation the importer will reconstruct the scheduling slot but not the behavior. This should be clearly documented and a warning raised so users are not surprised.
Dependency Ordering
One thing the importer must get right is construction order. Brian2 objects reference each other by name — a Synapses object needs its source and target NeuronGroup to already exist before it can be constructed. The correct order is:
Neuron groups and input sources (NeuronGroup, PoissonGroup, SpikeGeneratorGroup)
Synapses (reference source and target by name)
Monitors (reference their source objects)
Replay initializers_connectors in sequence variable assignments and connect() calls in the order they were originally made
Getting this wrong would cause silent bugs or outright crashes during reconstruction, so the importer must enforce this strictly rather than naively iterating the components dict.
Primary API I have in mind:
from brian2tools.baseimport import import_network
set_device('exporter')
... define and run network ...
exported = device.runs
net = import_network(exported)
net.run(100*ms) # reconstructed network runs identically
The importer should return a fully constructed Network object ready to run, with all objects, connections, and initial conditions restored. It should raise clear errors when the export contains components it cannot reconstruct (e.g. NetworkOperation function bodies) rather than silently skipping them.
Why This Matters
Without an importer:
Researchers cannot save and reload network architectures programmatically the export is essentially write-only
The exporter's own correctness cannot be verified bugs go undetected because there is no reconstruction step to expose them. A round-trip test (export → import → run → compare spike trains) is the only way to prove the exporter is producing correct output
Downstream tools like NWB export or ML framework interoperability cannot be built on a foundation that has not been round-trip verified - The GSoC serialization work as a whole has no completion criterion without this the exporter alone is not a usable feature
Summary
While working on the baseexport module I noticed that the serialization pipeline is entirely one-way. The exporter device produces a structured Python dictionary of a Brian2 network, but there is nothing on the other side that can consume it and reconstruct a runnable Network object. I'd like to propose and implement a basicimporter module that closes this gap and makes round-trip serialization possible for the first time.
This is a significant missing piece a researcher who exports their network architecture today has no programmatic way to reload it. They would have to manually re-write the Brian2 code from scratch using the exported dictionary as a reference, which defeats the purpose of having a structured export format at all.
Current State
When a user runs:
exported = device.runs # this is where it ends nothing can consume this device.runs contains a complete structured representation of the network equations, parameters, connectivity rules, initializers, monitor configurations but there is no import_network(exported) call that can turn it back into a runnable Brian2 network. The data is there, the consumer is not.
What the Current Exporter Is Still Missing
Before a correct importer can be written, I found a few gaps in the exporter that need to be addressed first:
The exporter stores equations as a parsed dictionary (per-variable type, unit, expr, flags). To pass them back into NeuronGroup(model=...), we need
a helper that reconstructs a valid Brian2 equation string from that dict. That direction is currently missing and will need to be part of the importer itself.
Dependency Ordering
One thing the importer must get right is construction order. Brian2 objects reference each other by name — a Synapses object needs its source and target NeuronGroup to already exist before it can be constructed. The correct order is:
Getting this wrong would cause silent bugs or outright crashes during reconstruction, so the importer must enforce this strictly rather than naively iterating the components dict.
Proposed Module Structure
Primary API I have in mind:
from brian2tools.baseimport import import_network
set_device('exporter')
... define and run network ...
exported = device.runs
net = import_network(exported)
net.run(100*ms) # reconstructed network runs identically
The importer should return a fully constructed Network object ready to run, with all objects, connections, and initial conditions restored. It should raise clear errors when the export contains components it cannot reconstruct (e.g. NetworkOperation function bodies) rather than silently skipping them.
Why This Matters
Without an importer:
Related