Adding morphologies#
This guide is a continuation of the 📚 Getting Started guide.
We’ve constructed a stacked double layer topology, and we have 2 cell types. We then connected them in an all-to-all fashion. A logical next step would be to assign morphologies to our cells, and connect them based on intersection!
A new model never contains any morphologies, and needs to fetch them from somewhere.
Projects are configured to fetch from a local file called morphologies.hdf5
. Any
morphologies you place in that file will be included in your model. An alternative to
morphologies.hdf5
is to fetch from different sources, like NeuroMorpho. We’ll go over
the different approaches.
Fetching from NeuroMorpho#
The framework can fetch morphologies for you from neuromorpho.org. Add a morphologies list to
your top_type
:
"top_type": {
"spatial": {
"radius": 7,
"count": 10,
"morphologies": [
{
"select": "from_neuromorpho",
"names": [
"cell005_GroundTruth",
"DD13-10-c8-3",
"10_666-GM9-He-Ctl-Chow-BNL16A-CA1Finished2e"
]
}
]
}
config.cell_types.add(
"top_type",
spatial=dict(
radius=7,
count=10,
morphologies=[
dict(
select="from_neuromorpho",
names=[
"cell005_GroundTruth",
"DD13-10-c8-3",
"10_666-GM9-He-Ctl-Chow-BNL16A-CA1Finished2e",
],
)
],
),
)
Tip
The morphologies attribute is a list. Each item in the list is a
selector
. Each selector selects a
set of morphologies from the repository, and those selections are added together and
assigned to the population.
Each item in the names attribute will be downloaded from NeuroMorpho. You can find the names on the neuron info pages:

Fetching from the local repository#
By default each model in a project will fetch from morphologies.hdf5
(check your
pyproject.toml
). You can import morphologies into this template repository by
importing local files, or constructing your own Morphology
objects, and saving them:
from bsb.storage import Storage
from bsb.morphologies import Morphology, Branch
morphologies = Storage("hdf5", "morphologies.hdf5").morphologies
# From file
morpho = Morphology.from_swc("my_neuron.swc")
morphologies.save("my_neuron", morpho)
# From objects
obj = Morphology([Branch([[0, 0, 0], [1, 1, 1]], [1])])
morphologies.save("my_obj", obj)
Hint
Download a morphology from NeuroMorpho and save it as my_neuron.swc
locally.
Afterwards, we add a NameSelector
to the base_type
:
"base_type": {
"spatial": {
"radius": 2,
"density": 1e-3,
"morphologies": [
{
"names": [
"my_neuron"
]
}
]
}
},
config.cell_types.base_type.spatial.morphologies = [
dict(
names=["my_neuron"],
)
]
Morphology intersection#
Now that our cell types are assigned morphologies we can use some connection strategies
that use morphologies, such as
VoxelIntersection
:
"connectivity": {
"A_to_B": {
"strategy": "bsb.connectivity.VoxelIntersection",
"presynaptic": {
"cell_types": ["base_type"]
},
"postsynaptic": {
"cell_types": ["top_type"]
}
}
}
config.connectivity.add(
"A_to_B",
strategy="bsb.connectivity.VoxelIntersection",
presynaptic=dict(cell_types=["base_type"]),
postsynaptic=dict(cell_types=["top_type"]),
)
Note
If there’s multiple morphologies per cell type, they’ll be assigned randomly, unless you
specify a MorphologyDistributor
.
Recap#
{
"name": "Starting example",
"storage": {
"engine": "hdf5",
"root": "network.hdf5"
},
"network": {
"x": 400.0,
"y": 600.0,
"z": 400.0
},
"regions": {
"brain_region": {
"type": "stack",
"children": ["base_layer", "top_layer"]
}
},
"partitions": {
"base_layer": {
"type": "layer",
"thickness": 100,
"stack_index": 0
},
"top_layer": {
"type": "layer",
"thickness": 100,
"stack_index": 1
}
},
"cell_types": {
"base_type": {
"spatial": {
"radius": 2,
"density": 1e-3,
"morphologies": [
{
"names": [
"my_neuron"
]
}
]
}
},
"top_type": {
"spatial": {
"radius": 7,
"count": 10,
"morphologies": [
{
"select": "from_neuromorpho",
"names": [
"cell005_GroundTruth",
"DD13-10-c8-3",
"10_666-GM9-He-Ctl-Chow-BNL16A-CA1Finished2e"
]
}
]
}
}
},
"placement": {
"base_placement": {
"strategy": "bsb.placement.ParticlePlacement",
"cell_types": ["base_type"],
"partitions": ["base_layer"]
},
"top_placement": {
"strategy": "bsb.placement.ParticlePlacement",
"cell_types": ["top_type"],
"partitions": ["top_layer"]
}
},
"connectivity": {
"A_to_B": {
"strategy": "bsb.connectivity.VoxelIntersection",
"presynaptic": {
"cell_types": ["base_type"]
},
"postsynaptic": {
"cell_types": ["top_type"]
}
}
}
}
from bsb.core import Scaffold
from bsb.config import from_json
from bsb.topology import Stack
from bsb.plotting import plot_network
import bsb.options
bsb.options.verbosity = 3
config = from_json("network_configuration.json")
config.partitions.add("top_layer", thickness=100, stack_index=1)
config.regions["brain_region"] = Stack(
children=[
"base_layer",
"top_layer",
]
)
config.cell_types.base_type.spatial.morphologies = [
dict(
names=["my_neuron"],
)
]
config.cell_types.add(
"top_type",
spatial=dict(
radius=7,
count=10,
morphologies=[
dict(
select="from_neuromorpho",
names=[
"cell005_GroundTruth",
"DD13-10-c8-3",
"10_666-GM9-He-Ctl-Chow-BNL16A-CA1Finished2e",
],
)
],
),
)
config.placement.add(
"all_placement",
strategy="bsb.placement.ParticlePlacement",
cell_types=["base_type", "top_type"],
partitions=["base_layer"],
)
config.connectivity.add(
"A_to_B",
strategy="bsb.connectivity.VoxelIntersection",
presynaptic=dict(cell_types=["base_type"]),
postsynaptic=dict(cell_types=["top_type"]),
)
network = Scaffold(config)
network.compile()
plot_network(network)