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:

../_images/nm_what.png

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)