################## Your first network ################## Make sure you completed the :doc:`Installation guide` before running the example in this section. .. note:: | This guide aims to get your first model running with the minimum number of steps. | If you would like to familiarize yourself with the core concepts and get a more top level understanding first, check out the :doc:`/config/files` before you continue. The framework supports both declarative statements in configuration formats, or Python code. Be sure to take a quick look at each code tab to get a feel for the equivalent forms of configuration coding! Create a project ================ Use the command below to create a new BSB project directory and some starter files: .. code-block:: bash bsb new my_first_model --quickstart --json cd my_first_model Projects help you keep your models organized, safe, and neat! Your folder should contain: * ``network_configuration.json``: your configuration file. The components are declared and parametrized here. * A ``pyproject.toml`` file: This file uses the TOML syntax to set configuration values for the BSB and any other python tools your project uses. * A ``placement.py`` and ``connectome.py`` files if you want to make your own components. Python project settings are contained in the ``pyproject.toml`` file. A lot of Python options can be configured with your ``toml`` file such as the python libraries necessary to deploy it. If you want to learn more about this configuration tool, check out `this tutorial `_ and the :doc:`bsb related options `. The configuration contains already a :guilabel:`partition` ``base_layer``, a :guilabel:`cell_type` ``base_type`` and a :guilabel:`placement` strategy ``example_placement``. These minimal components are enough to *compile* your first network. You can do this from the terminal or with Python: .. tab-set-code:: .. code-block:: bash bsb compile --verbosity 3 .. code-block:: python import bsb.options from bsb import Scaffold, parse_configuration_file bsb.options.verbosity = 3 config = parse_configuration_file("network_configuration.json", parser="json") scaffold = Scaffold(config) scaffold.compile() Here, the ``verbosity`` flag increases the amount of output (logs) that is generated when the BSB is running, to follow along or troubleshoot. When the BSB compiles a `Scaffold`, it extracts and runs the reconstruction pipeline defined in the `Configuration` and stores each step's results into the `Storage` (as explained in the :ref:`previous section `). The compile command (or python script) should produce a file ``"network.hdf5"`` located in your project folder if the BSB could parse the configuration file and complete the reconstruction. This file should contain your network (configuration and storage) after reconstruction. .. note:: The configuration file can be written in either ``json`` or ``yaml`` format; By default, the :guilabel:`new` command uses the yaml format unless the ``--json`` flag is set. If you prefer, instead of loading the configuration from a file, you can create your configuration directly in Python code with a ``Configuration`` object: .. code-block:: python import bsb.options from bsb import Scaffold, Configuration bsb.options.verbosity = 3 config = Configuration.default(storage=dict(engine="hdf5", root="network.hdf5")) # Implement your code here scaffold = Scaffold(config) scaffold.compile() .. _getting-started-configurables: Define starter components ========================= Network ------- The ``network`` component describes the global spatial properties of your circuit, including its size along the three dimensions :guilabel:`x`, :guilabel:`y`, :guilabel:`z` (in µm). .. tab-set-code:: .. literalinclude:: configs/getting-started.json :language: json :lines: 7-11 .. literalinclude:: /../examples/tutorials/getting_started.py :language: python :lines: 7-9 Topology -------- Your network model needs a description of its shape, which is called the topology of the network. The topology consists of 2 components: :doc:`Regions ` and :doc:`Partitions `. Regions combine multiple partitions and/or regions together, in a hierarchy, all the way up to a single topmost region, while partitions are exact pieces of volume that can be filled with cells. To get started, we will add a second layer ``top_layer``, and a region ``brain_region``: .. tab-set-code:: .. literalinclude:: configs/getting-started.json :language: json :lines: 12-27 .. literalinclude:: /../examples/tutorials/getting_started.py :language: python :lines: 11-20 The :guilabel:`type` of the ``brain_region`` is ``stack``. This means it will place its children stacked on top of each other. The :guilabel:`type` of ``base_layer`` is ``layer``. Layers specify their size in one dimension, and fill up the space in the other dimensions. See the :doc:`topology section` for more explanation on these components. .. warning:: The BSB checks the configuration for errors each time the latter is modified. Now, in the Python code implementation, we are adding components one by one. This means that if one component refers to another, this latter should already in the configuration. That is why, in the python code implementation, we created the partitions before the region because the region uses references to the partitions' name. Cell types ---------- The :doc:`Cell Types ` define populations of cells. In the simplest case, you can define a ``cell type`` by its soma :guilabel:`radius` and the number of cells to place using either a :guilabel:`density` value, or a fixed :guilabel:`count`, or another :doc:`placement indication `. To populate our new ``top_layer``, we will create an extra cell type ``top_type``; this time we want to a place 40 of these cells and their soma :guilabel:`radius` of ``7``. .. tab-set-code:: .. literalinclude:: configs/getting-started.json :language: json :lines: 28-41 .. literalinclude:: /../examples/tutorials/getting_started.py :language: python :lines: 22-29 Placement --------- The :doc:`placement ` blocks are in charge of placing cells in the partitions using the cell type indications. For each placement component, you should specify the placement :guilabel:`strategy` to use, the list of :guilabel:`cell_types` names to place and the list of :guilabel:`partitions` in which you want the placement to happen. Now that we have defined our new ``top_type``, we should place it in our ``top_layer``: .. tab-set-code:: .. literalinclude:: configs/getting-started.json :language: json :lines: 42-53 .. literalinclude:: /../examples/tutorials/getting_started.py :language: python :lines: 31-42 We added here the ``top_placement`` strategy. ``top_placement`` and ``example_placement`` are both following a ``RandomPlacement`` strategy from the BSB, which assigns a random position to the cells' soma within their respective partition. You should now try to compile your network to check if you did no mistake: .. tab-set-code:: .. code-block:: bash bsb compile -v 3 --clear .. code-block:: python # bsb.options.verbosity = 3 # if not set previously scaffold.compile(clear=True) .. note:: We are using the short forms ``-v`` of the CLI options ``verbosity``. You can use ``bsb --help`` to inspect the :doc:`CLI options `. .. warning:: We pass the ``clear`` flag to indicate that existing data may be overwritten. See :ref:`storage_control` for more flags to deal with existing data. Each placement strategy generates a `PlacementSet` in the `Storage` that you can access from the `Scaffold` object (see :doc:`this section ` for more info). Connectivity ------------ The :doc:`connectivity ` component contains the blocks that specify connections between systems of cell types. For each :guilabel:`connectivity` component, you should specify the connection :guilabel:`strategy` and for both :guilabel:`presynaptic` (source) and :guilabel:`postsynaptic` (target) groups, provide the list of :guilabel:`cell_types` names to connect. Here, we are going to connect all ``base_type`` cells to all ``top_type`` cells. .. tab-set-code:: .. literalinclude:: configs/getting-started.json :language: json :lines: 54-65 .. literalinclude:: /../examples/tutorials/getting_started.py :language: python :lines: 44-49 Recompile the network once more, now it will also contain your connections! With your cells and connections in place, you are ready to move to the next stage. .. note:: For Python, the `compile` function should be called (only once) at the end of your script, once the configuration is complete. Each connection strategy generates a `ConnectivitySet` in the `Storage` for each pair of cell types that you can access from the `Scaffold` object (see :doc:`this section ` for more info). Here, the name of the `ConnectivitySet` corresponds to the connection component (``A_to_B``) because there is only one pair of :guilabel:`cell_type`. .. warning:: If you have more than one pair of cell types connected through the same connection strategy, then the name of the `ConnectivitySet` is ``NameOfTheComponent`` _ ``NameOfPreType`` _ ``NameOfPostType`` (learn more `here`). Final configuration file ------------------------ .. tab-set-code:: .. literalinclude:: configs/getting-started.json :language: json .. literalinclude:: /../examples/tutorials/getting_started.py :language: python What is next? ============= Learn how to extract the data from your produced `Scaffold` through :doc:`this tutorial `.