diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d45934f3..6e8c2257 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: api: uses: ./.github/workflows/api.yml - tag_release: + bump: needs: [isort, black, build, docs, api] runs-on: ubuntu-latest outputs: @@ -44,35 +44,55 @@ jobs: with: token: ${{ steps.app-token.outputs.token }} branch: main + noVersionBumpBehavior: warn + + tag_release: + needs: [ bump ] + # Skip job in case no version bump is required + # in this case the variable tag will not be set by semver + if: ${{ needs.bump.outputs.tag != ''}} + runs-on: ubuntu-latest + steps: + - name: Create Github token + uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.DBBS_APP_ID }} + private-key: ${{ secrets.DBBS_APP_PRIVATE_KEY }} + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ steps.app-token.outputs.token }} - name: Set up Python 3.11 - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: 3.11 - name: Bump version in Python project run: | pip install --upgrade pip bump-my-version - oldv="${{ steps.semver.outputs.current }}" - newv="${{steps.semver.outputs.next}}" + oldv="${{ needs.bump.outputs.old_tag }}" + newv="${{needs.bump.outputs.tag}}" # Bump the version, dropping the leading `v` with `${x:1}` bump-my-version replace --current-version=${oldv:1} --new-version=${newv:1} pyproject.toml - name: Commit & Push version change - uses: stefanzweifel/git-auto-commit-action@v4 + uses: stefanzweifel/git-auto-commit-action@v5 with: branch: main - commit_message: 'docs: bump version: ${{ steps.semver.outputs.current }} → ${{ steps.semver.outputs.next }} [skip ci]' + commit_message: 'docs: bump version: ${{ needs.bump.outputs.old_tag }} → ${{ needs.bump.outputs.tag }} [skip ci]' - name: Create tag uses: rickstaa/action-create-tag@v1 with: - tag: ${{ steps.semver.outputs.next }} + tag: ${{ needs.bump.outputs.tag }} github_token: ${{ steps.app-token.outputs.token }} release: runs-on: ubuntu-latest - needs: tag_release + needs: [bump, tag_release] steps: - name: Create Github token @@ -97,8 +117,8 @@ jobs: uses: requarks/changelog-action@v1 with: token: ${{ steps.app-token.outputs.token }} - fromTag: ${{ needs.tag_release.outputs.tag }} - toTag: ${{ needs.tag_release.outputs.old_tag }} + fromTag: ${{ needs.bump.outputs.tag }} + toTag: ${{ needs.bump.outputs.old_tag }} - name: Create Release uses: ncipollo/release-action@v1.12.0 @@ -106,13 +126,13 @@ jobs: allowUpdates: true draft: false makeLatest: true - tag: ${{ needs.tag_release.outputs.tag }} - name: ${{ needs.tag_release.outputs.tag }} + tag: ${{ needs.bump.outputs.tag }} + name: ${{ needs.bump.outputs.tag }} body: ${{ steps.changelog.outputs.changes }} token: ${{ steps.app-token.outputs.token }} - name: Commit CHANGELOG.md - uses: stefanzweifel/git-auto-commit-action@v4 + uses: stefanzweifel/git-auto-commit-action@v5 with: branch: main commit_message: 'docs: update CHANGELOG.md for ${{ github.ref_name }} [skip ci]' diff --git a/README.md b/README.md index 5369f0a2..84594599 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ # BSB: A component framework for neural modelling Developed by the Department of Brain and Behavioral Sciences at the University of Pavia, -the BSB is a component framework for neural modelling, which focusses on component +the BSB is a component framework for neural modelling, which focuses on component declarations to piece together a model. The component declarations can be made in any supported configuration language, or using the library functions in Python. It offers parallel reconstruction and simulation of any network topology, placement and/or @@ -29,7 +29,7 @@ pip install "bsb" ``` Advanced users looking to control install an unconventional combination of plugins might -be better of installing just this package, and the desired plugins: +be better off installing just this package, and the desired plugins: ``` pip install "bsb-core" @@ -65,20 +65,28 @@ bsb new my_model --quickstart cd my_model ``` +This will create a `my_model` folder for you with some starter files. It should contain: + +- `network_configuration.yaml`: A configuration file in which your network will be described. +- A `pyproject.toml` file: This file uses the TOML syntax to set configuration values for the BSB. +- A `placement.py` and `connectome.py` files if you want to make your own components. + ### Reconstructing a network -You can use your project to create reconstructions of your model, generating cell positions +Within your project folder, you can create reconstructions of your model, generating cell positions and connections: ``` -bsb compile -p +bsb compile ``` -This creates a [network file](bsb.readthedocs.io/getting-started/networks.html) and plots the network. +The `compile` command should produce a network file located in your project +folder based on your configuration file. ### Simulating a network -The default project currently contains no simulation config. +The starter project contains no simulation configuration but the documentation provides tutorials +for the neural simulators supported by the BSB. # Contributing diff --git a/bsb/cli/commands/_commands.py b/bsb/cli/commands/_commands.py index d60ea956..97d911c2 100644 --- a/bsb/cli/commands/_commands.py +++ b/bsb/cli/commands/_commands.py @@ -207,7 +207,7 @@ def handler(self, context): for name, sim in extra_simulations.items(): if name not in network.simulations and name == sim_name: network.simulations[sim_name] = sim - root = pathlib.Path(getattr(context.arguments, "output_folder", "./")) + root = pathlib.Path(getattr(context.arguments, "output-folder", "./")) if not root.is_dir() or not os.access(root, os.W_OK): return report( f"Output provided '{root.absolute()}' is not an existing directory with write access.", @@ -231,7 +231,7 @@ def get_options(self): def add_parser_arguments(self, parser): parser.add_argument("network") parser.add_argument("simulation") - parser.add_argument("-o", "--output_folder") + parser.add_argument("-o", "--output-folder") class CacheCommand(BaseCommand, name="cache"): # pragma: nocover diff --git a/bsb/config/_distributions.py b/bsb/config/_distributions.py index dffe1aa1..63e35274 100644 --- a/bsb/config/_distributions.py +++ b/bsb/config/_distributions.py @@ -29,7 +29,7 @@ class Distribution: ) """Name of the scipy.stats distribution function""" parameters: dict[str, typing.Any] = config.catch_all(type=types.any_()) - """parameters to pass to the distribution""" + """Parameters to pass to the distribution""" def __init__(self, **kwargs): if self.distribution == "constant": diff --git a/bsb/connectivity/strategy.py b/bsb/connectivity/strategy.py index 5dc7e588..3a0723b5 100644 --- a/bsb/connectivity/strategy.py +++ b/bsb/connectivity/strategy.py @@ -168,7 +168,7 @@ def connect(self, presyn_collection, postsyn_collection): Central method of each connection strategy. Given a pair of ``HemitypeCollection`` (one for each connection side), should connect cell population using the scaffold's (available as ``self.scaffold``) - :func:`~bsb.core.Scaffold.connect_cells` method. + :meth:`bsb.core.Scaffold.connect_cells` method. :param bsb.connectivity.strategy.HemitypeCollection presyn_collection: presynaptic filtered cell population. diff --git a/bsb/core.py b/bsb/core.py index 1dcf9e79..7b9e0c6c 100644 --- a/bsb/core.py +++ b/bsb/core.py @@ -795,7 +795,7 @@ def create_job_pool(self, fail_fast=None, quiet=False): ) try: # Check whether stdout is a TTY, and that it is larger than 0x0 - # (e.g. MPI sets it to 0x0 unless a xterm is emulated. + # (e.g. MPI sets it to 0x0 unless an xterm is emulated). tty = os.isatty(sys.stdout.fileno()) and sum(os.get_terminal_size()) except Exception: tty = False diff --git a/bsb/mixins.py b/bsb/mixins.py index e6c65baa..6f5275bc 100644 --- a/bsb/mixins.py +++ b/bsb/mixins.py @@ -27,11 +27,10 @@ def _all_chunks(iter_): def _queue_connectivity(self, pool: "JobPool"): - """Get the queued jobs of all the strategies we depend on. + """ + Get the queued jobs of all the strategies we depend on. - Parameters - ---------- - param pool : pool where the jobs will be queued + param pool: pool where the jobs will be queued type pool: bsb.services.pool.JobPool """ deps = set(_gutil.ichain(pool.get_submissions_of(strat) for strat in self.get_deps())) diff --git a/docs/cells/intro.rst b/docs/cells/intro.rst index 3f0e6d04..9bcee023 100644 --- a/docs/cells/intro.rst +++ b/docs/cells/intro.rst @@ -2,21 +2,18 @@ Cell Types ========== -A cell types contains information about cell populations. There are 2 categories: cells, -and entities. A cell has a position, while an entity does not. Cells can also have -morphologies and orientations associated with them. On top of that, both cells and -entities support additional arbitrary properties. - -A cell type is an abstract description of the population. During placement, the concrete -data is generated in the form of a :doc:`PlacementSet `. These can -then be connected together into :class:`ConnectivitySets +A cell type is an abstract description of a cell population. Cell populations are +placed within `Partitions` according to :doc:`placement indications `. +You can also attach morphologies and orientations to them. +During placement, the cell positions are generated in the form of a :doc:`PlacementSet `. +These can then be connected together into :class:`ConnectivitySets <.storage.interfaces.ConnectivitySet>`. Furthermore, during simulation, cell types are represented by **cell models**. .. rubric:: Basic configuration -The :guilabel:`radius` and :guilabel:`density` are the 2 most basic :doc:`placement -indications `, they specify how large and dense the cells in the population generally are. +The :guilabel:`radius` and :guilabel:`density` are the 2 most basic :doc:`placement indications `: +they specify how large and dense the cells in the population generally are. The :guilabel:`plotting` block allows you to specify formatting details. .. tab-set-code:: @@ -47,10 +44,12 @@ The :guilabel:`plotting` block allows you to specify formatting details. .. rubric:: Specifying spatial density -You can set the spatial distribution for each cell type present in a -:ref:`NrrdVoxels ` partition. +In the previous example, we were setting the number of cells to place within each partition +based on a single density value. Let's imagine now that you want to describe the spatial +distribution of the cell type spatial density for each voxel within your partition. +This can be achieved with the :ref:`NrrdVoxels ` partition. -To do so, you should first attach your nrrd volumetric density file(s) to the partition with either +To do so, you should first attach your NRRD volumetric density file(s) to the partition with either the :guilabel:`source` or :guilabel:`sources` blocks. Then, label the file(s) with the :guilabel:`keys` list block and refer to the :guilabel:`keys` in the :guilabel:`cell_types` with :guilabel:`density_key`: @@ -111,25 +110,26 @@ in the :guilabel:`cell_types` with :guilabel:`density_key`: ) config.cell_types.add( - "first_cell_type", - spatial=dict(radius=10, density_key="first_cell_type_density") - plotting=dict(display_name="First Cell Type", color="pink",opacity="1.0") + "first_cell_type", + spatial=dict(radius=10, density_key="first_cell_type_density") + plotting=dict(display_name="First Cell Type", color="pink",opacity="1.0") ) config.cell_types.add( - "second_cell_type", - spatial=dict(radius=10, density_key="second_cell_type_density") - plotting=dict(display_name="First Cell Type", color="#0000FF",opacity="0.5") + "second_cell_type", + spatial=dict(radius=10, density_key="second_cell_type_density") + plotting=dict(display_name="First Cell Type", color="#0000FF",opacity="0.5") ) -The nrrd files should contain voxel based volumetric density in unit of cells / voxel volume, +The NRRD files should contain voxel based volumetric density in unit of cells / voxel volume, where the voxel volume is in cubic unit of :guilabel:`voxel_size`. i.e., if :guilabel:`voxel_size` is in µm then the density file is in cells/µm^3. +This implementation corresponds to an atlas-based reconstruction and you can find an example of +a BSB configuration using the Allen Atlas in :doc:`this section ` . .. rubric:: Specifying morphologies - -To associate a cell type with a specific morphology, add the desired morphology to the cells by referencing -the corresponding name stored in the :doc:`morphology repository `. +The easiest way to associate a morphology to a cell type is by referencing the name it is stored under. +There are more advanced ways as well, covered in our guide on :ref:`Morphology Selectors ` . .. tab-set-code:: @@ -162,4 +162,5 @@ the corresponding name stored in the :doc:`morphology repository `. diff --git a/docs/cli/commands.rst b/docs/cli/commands.rst index bcf99be3..a43b41b0 100644 --- a/docs/cli/commands.rst +++ b/docs/cli/commands.rst @@ -27,7 +27,7 @@ project settings. * ``quickstart``: Generates an exemplary project with basic config that can be compiled. * ``exists``: With this flag, it is not an error for the ``parent-folder`` to exist. * ``json``: With this flag, the configuration file will be written in the JSON format - instead of YAML format used by default. + instead of the default YAML format. .. _bsb_make_config: diff --git a/docs/cli/intro.rst b/docs/cli/intro.rst index d8c2a7f3..5357f7cb 100644 --- a/docs/cli/intro.rst +++ b/docs/cli/intro.rst @@ -4,7 +4,6 @@ Introduction ############ -The command line interface is composed of a collection of pluggable commands. Open up your favorite terminal and enter the ``bsb --help`` command to verify you correctly installed the software. diff --git a/docs/components/components.rst b/docs/components/components.rst index 8e5d8031..79b98f31 100644 --- a/docs/components/components.rst +++ b/docs/components/components.rst @@ -10,10 +10,9 @@ out of the box components for basic operations, but often you'll need to write y If you want to read a step by step tutorial on how to make your own component, check this :doc:`page ` -For each component, BSB provides interfaces, each with a set of functions that you must -implement. If these functions are present, the framework knows how to use your class. - -Hence, the framework allows you to plug in user code pretty much anywhere. Neat. +For each component, the BSB provides interfaces, each with a set of functions that you must +implement. By implementing these functions, the framework can seamlessly integrate your +custom components into a BSB workflow. Neat! Here is how you do it (theoretically): diff --git a/docs/conf.py b/docs/conf.py index 1aff02d8..880b55b9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -79,7 +79,6 @@ "mpi4py": ("https://mpi4py.readthedocs.io/en/stable/", None), "arbor": ("https://docs.arbor-sim.org/en/latest/", None), "neo": ("https://neo.readthedocs.io/en/latest/", None), - "bsb": ("https://bsb.readthedocs.io/en/latest", None), } # Add any paths that contain templates here, relative to this directory. diff --git a/docs/getting-started/simulations/guide_nest.rst b/docs/getting-started/simulations/guide_nest.rst index d021154e..14d5f462 100644 --- a/docs/getting-started/simulations/guide_nest.rst +++ b/docs/getting-started/simulations/guide_nest.rst @@ -326,7 +326,7 @@ You can now run your simulation: The results of the simulation will be stored in the ``"simulation-results"`` folder. .. note:: - If you run the simulation with the command line interface, the name of the output nio file is randomized by BSB. + If you run the simulation with the command line interface, the name of the output nio file is randomized by the BSB. For more detailed information about simulation modules, please refer to the :doc:`simulation section `. diff --git a/docs/getting-started/simulations/toc_point_neurons.rst b/docs/getting-started/simulations/toc_point_neurons.rst index d53a0672..445219be 100644 --- a/docs/getting-started/simulations/toc_point_neurons.rst +++ b/docs/getting-started/simulations/toc_point_neurons.rst @@ -1,9 +1,9 @@ -Guides on Point neurons simulation +Guides on Point-neuron simulations ================================== .. toctree:: :maxdepth: 2 - :caption: Point neuron simulations + :caption: Point-neuron simulations guide_nest analyze_spikes \ No newline at end of file diff --git a/docs/getting-started/top-level-guide.rst b/docs/getting-started/top-level-guide.rst index b70dba4f..cb4fbd6d 100644 --- a/docs/getting-started/top-level-guide.rst +++ b/docs/getting-started/top-level-guide.rst @@ -20,7 +20,7 @@ A typical workflow of the BSB works as follows: 1. The user provides a configuration that describes the network they want to reconstruct and simulate. - It is interpreted by BSB as a list of tasks to perform. + It is interpreted by the BSB as a series of tasks to perform. 2. The BSB creates the topology of the network (i.e., its shape and size). 3. The BSB places cells within the network, following a defined strategy. 4. The BSB connects the aforementioned cells according to connectivity rules. @@ -55,7 +55,7 @@ storage object full of neuroscience. To do so, the configuration leverages configurable objects to describe the underlying neural network, called **components**. Components define which methods and parameters should be used to reconstruct and -simulate the network. The ones that you would probably employ the most are: +simulate the network. The ones that you will probably employ the most are: * :guilabel:`Topology` defines the shape and volume of your network, (it is composed of :guilabel:`Regions` and :guilabel:`Partitions`), @@ -63,7 +63,10 @@ simulate the network. The ones that you would probably employ the most are: (and attach :guilabel:`Morphologies` when needed), * :guilabel:`Placement` places cells, * :guilabel:`Connectivity` connect cells, -* :guilabel:`Simulation` simulates the resulting network. +* :guilabel:`Simulation` simulates the resulting network. Each simulation consists of: + * :guilabel:`Cell Models` describe how to simulate a cell. + * :guilabel:`Connection Models` describe how to simulate cellular connections such as synapses and gap junctions. + * :guilabel:`Devices` describe the experimental setup by ways of input stimuli, recording devices, LFP probes, etc. Assembled together these components form a linear workflow that will build your network from scratch. @@ -78,9 +81,18 @@ Configuration ============= The ``Configuration`` object is organized as a hierarchical tree. -From the root, the main blocks branch off, consisting of nine main components: :guilabel:`network`, -:guilabel:`storage`, :guilabel:`regions`, :guilabel:`partitions`, :guilabel:`morphologies`, :guilabel:`cell_types`, -:guilabel:`placement`, :guilabel:`connectivity`, and :guilabel:`simulation`. +From the root, the main blocks branch off, consisting of nine main components: + +* :guilabel:`network` +* :guilabel:`storage` +* :guilabel:`regions` +* :guilabel:`partitions` +* :guilabel:`morphologies` +* :guilabel:`cell_types` +* :guilabel:`placement` +* :guilabel:`connectivity` +* :guilabel:`simulation` + These blocks contain nested sub-blocks that form the network. Additionally, there are two optional components: :guilabel:`after_placement` and :guilabel:`after_connectivity`, where users can define specific hooks to run within the workflow. @@ -96,7 +108,7 @@ All these components will be described in more detail in the following sections. The configuration object contains only the description of the model, not its implementation (python code) nor its data (stored in the storage object). -It can therefore be stored in a separate file (usually Json or Yaml) that can be easily interpreted by BSB. +It can therefore be stored in a separate file (usually Json or Yaml) that can be easily interpreted by the BSB. What is next? ============= diff --git a/docs/morphologies/intro.rst b/docs/morphologies/intro.rst index b965cd90..f7c7efa5 100644 --- a/docs/morphologies/intro.rst +++ b/docs/morphologies/intro.rst @@ -378,6 +378,8 @@ passed around in the framework as :class:`StoredMorphologies :class:`~.morphologies.Morphology` object from storage and a :meth:`~.storage.interfaces.StoredMorphology.get_meta` method to return the metadata. +.. _morphology_selector: + Morphology selectors -------------------- diff --git a/pyproject.toml b/pyproject.toml index e7c64bfb..27ad93dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,6 @@ dependencies = [ "numpy~=1.19", "scipy~=1.5", "scikit-learn~=1.0", - "colour~=0.1", "errr~=1.2", "rtree~=1.0", "psutil~=5.8",