Skip to content

feat: Add simulation's controllers#169

Merged
filimarc merged 41 commits intonextfrom
feature/sim-controllers
Oct 14, 2025
Merged

feat: Add simulation's controllers#169
filimarc merged 41 commits intonextfrom
feature/sim-controllers

Conversation

@filimarc
Copy link
Contributor

@filimarc filimarc commented Sep 3, 2025

Technical proposal and requirements

Impact

  • This feature will control the start-stop behavior of simulations.
  • It may impact simulation performance.
  • It impacts the simulation progress interfaces and progress listeners (by default there are no progress listeners, or configuration for it).

Current Behavior

  • In Arbor: no start-stop: run simulation from start to finish.
  • In NEST: start-stop in 1ms blocks.
  • In NEURON start-stop in 1ms blocks.

N.B.: resolution config attr only affects simulation resolution, not start-stop behavior.

Context

Sometimes devices or other simulation components need to execute a callback at certain checkpoints. The current use case is LFP where the recorded data of the entire simulation exceeds memory capacity, but one can calculate less memory intense intermediates and flush the recorded data in between.

Desired Behavior

Technical proposal

We introduce a concept of "simulation controllers" which are simulation components that implement get_next_checkpoint. Without any controllers present, simulation should run from start to finish without steps (breaking change), no progress listeners triggered.

Uniformizing implement

The implement interface should be lifted from Device to SimulationComponent and be made optional for all components, and called the same way it's done for Devices now to give each component the opportunity to store the context they need to operate. The implement function should remain required for devices.

Finding the "controllers":

def prepare():
  # ...
  controllers = [*(d for d in simulation.devices if hasattr(d, "get_next_checkpoint")), *(<same for cell_models>), *(<same for connection_models>)]

And honestly let's just add a util function get_simulation_components that returns an iterator with all of the components, and then:

def prepare():
  # ...
  controllers = [*(comp for comp in get_simulation_components(simulation) if hasattr(comp, "get_next_checkpoint"))]

run_checkpoint

A required callback to be ran at requested checkpoints.

Note

  • We have to request the arbor.clear_samples(handle) feature to the arbor dev team
  • We need to ask the NEST devs if it's possible to clear recorded data during a simulation

As a workaround, run_checkpoints in Arbor may clear all the samples, but should take care so that all devices in the simulation first get flushed, so that no data is lost.

get_next_checkpoint

At the start of the simulation, and at each checkpoint, call all get_next_checkpoint and find the closest one (min). Thenh store all controllers, that requested this checkpoint. At the checkpoint, run all run_checkpoint functions of those controllers:

Controller A requests: 3, 10, 16
Controller B requests: 4,  10, 12

Then checkpoints are: 3, 4, 10, 12, 16
And run_checkpoint is called for A at requested checkpoints, and B requested checkpoints

FixedStepController

Provide component to do simple fixed step, which also adds a progress listener that prints progress or shows progress bar in TTY. Add option to control addition of this controller to simulations, with configuration of time step. Its goal is that the user has a simple way of start-stopping simulation in certain intervals with progress reporting.

Describe the work done

  • Now the implement method is raised to SimulationComponent level, it still need to be implemented for Devices.
  • The method create_device (or prepare_samples for Arbor) is substitute with implement_components() that is general for all the adapters.
  • Now every adapter has a _controllers list where selected controllers (can be any simulation components) can be registered, if it has get_next_checkpoint and progress methods.
  • In the Adapter is implemented a get_next_checkpoint method that creates an iterator that span all the registered controllers for the next checkpoint
  • before simulation starts the adapter will look for controllers with on_start() method an run them.
  • Is created a BasicSimulationListener class, can be added with a new BsbOption ( --sr). In the presence of a TTY terminal the simulation execution is now rendered as a progress bar.
  • Interface for add custom listeners is removed

Tasks

  • Added tests
  • Updated documentation

📚 Documentation preview 📚: https://bsb-arbor--169.org.readthedocs.build/en/169/


📚 Documentation preview 📚: https://bsb-nest--169.org.readthedocs.build/en/169/


📚 Documentation preview 📚: https://bsb-core--169.org.readthedocs.build/en/169/


📚 Documentation preview 📚: https://bsb-neuron--169.org.readthedocs.build/en/169/


📚 Documentation preview 📚: https://bsb--169.org.readthedocs.build/en/169/


📚 Documentation preview 📚: https://bsb-test--169.org.readthedocs.build/en/169/

@github-actions github-actions bot added the feat label Sep 3, 2025
@codecov
Copy link

codecov bot commented Sep 3, 2025

Codecov Report

❌ Patch coverage is 81.25000% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.85%. Comparing base (812a974) to head (48ac68a).

Files with missing lines Patch % Lines
packages/bsb-core/bsb/simulation/adapter.py 76.92% 13 Missing and 2 partials ⚠️
packages/bsb-arbor/bsb_arbor/devices/probe.py 33.33% 2 Missing ⚠️
packages/bsb-neuron/bsb_neuron/adapter.py 75.00% 2 Missing ⚠️
...ages/bsb-arbor/bsb_arbor/devices/spike_recorder.py 66.66% 0 Missing and 1 partial ⚠️
packages/bsb-core/bsb/_options.py 85.71% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             next     #169      +/-   ##
==========================================
+ Coverage   78.78%   78.85%   +0.07%     
==========================================
  Files         121      143      +22     
  Lines       12545    13596    +1051     
  Branches     1385     1505     +120     
==========================================
+ Hits         9883    10721     +838     
- Misses       2318     2499     +181     
- Partials      344      376      +32     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

filimarc and others added 11 commits September 4, 2025 14:29
* add get_components() in Simulation
* raise implement() to SimulationComponent level
* BasicListener is no longer inserted by default
* switch from prepare_samples to implement for Arbor devices
* remove need_flush usage

* create_device method is substitute by implement_components
* Now there is a check for sim report option in adapter.simulate()
@filimarc filimarc changed the title feat: Add simulation's AdapterControllers feat: Add simulation's controllers Sep 19, 2025
@filimarc filimarc marked this pull request as ready for review September 19, 2025 07:28
@filimarc filimarc requested a review from Helveg October 1, 2025 06:54
Copy link
Contributor

@Helveg Helveg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a mess of the review, but most parts are still not as discussed in the technical proposal. Can we have a call?

* remove on_start()
* do not use numpy in get_next_checkpoint()
* clean and rename
@filimarc filimarc requested a review from Helveg October 6, 2025 13:47
@filimarc filimarc requested a review from Helveg October 10, 2025 13:39
@filimarc filimarc merged commit 6edfbb8 into next Oct 14, 2025
29 checks passed
@filimarc filimarc deleted the feature/sim-controllers branch October 14, 2025 06:28
drodarie added a commit that referenced this pull request Nov 14, 2025
* feat!: multiple synapses per connections for NEST (#148)

* feat: allow multiple synapse per NEST connection

fix #145

* test: add unittests for multi synapses

* fix: make delay not required for synapses that do not use it.

fix #146

* docs: fix guide_nest.rst

* chore: test nx vars for affected

* chore: cleanup

* fix: use r0manchak/nx-set-shas to get proper affected projects

* fix: test with manual fetching of BASE and HEAD

* fix: add missing quotes

* fix: pass NX var to command

* fix: gha for build and pull_request

* fix: second try with r0manchak/nx-set-shas

* fix: test without origin and with HEAD

* fix: test with origin and with HEAD

* fix: sending of coverage

* fix: missing square brackets

* fix: missing parenthesis Cylindrical targetting

* fix: move synaptic parameters tests to NestSynapseSettings

* Update packages/bsb-nest/bsb_nest/connection.py

Co-authored-by: Robin De Schepper <robin.deschepper93@gmail.com>

* fix: refactor NestConnectionSettings to have only one rule and set of constants

* fix: `insert_transmitter` unique under NEURON 9 (#177)

* feat(arborize): added a way to control the next id tag of schematics

* prevent issue 159

* removed test prints and addressed review comments

* fix: lint

---------

Co-authored-by: Robin De Schepper <robin@alexandria.sc>
Co-authored-by: drodarie <d.rodarie@gmail.com>

* fix: click default value test for None values

See click release notes for v8.3

* chore(release): 6.0.7 [skip ci]

* fix: use nest.CollocatedSynapses for connections built with NEST rule

* test: add comments to unit tests

---------

Co-authored-by: Robin De Schepper <robin.deschepper93@gmail.com>
Co-authored-by: Robin De Schepper <robin@alexandria.sc>
Co-authored-by: DBBS Laboratory <neurocomp_dbbs@unipv.it>

* feat: Add simulation's  controllers (#169)

* feat: start to add the possibility to register and use simulation's controllers

* test: Add test for async ending | remove AdapterProgress
* add get_components() in Simulation
* raise implement() to SimulationComponent level
* switch from prepare_samples to implement for Arbor devices
* create_device method is substitute by implement_components
* feat: give option to set a FixedStepProgressController at start

---------

Co-authored-by: filimarc <filippo.marchetti@unipv.it>

* fix: correctly call synapse point process in arborize neuron builder  (#181)

* fix: correct call for synapse point process in neuron builders

* test: add small test for insert_receiver

* fix: add a patch for test synapse to clear the syn added by test receiver

* chore: switch to NEURON 9

* test: refactor test

* test: refactor test

---------

Co-authored-by: filimarc <filippo.marchetti@unipv.it>

* feat: Added experimental OpenTelemetry integration (#184)

* trace CLI context

* instrument node and command. add log events

* add otel api dep

* leave note on inf recurse in closure patching

* propagate otel ctx in job threads

* instrument node classes

* align option names to namespace names for easier inspection

* instrument commands

* removed meter code, moved otel code to profiling

* should auto classmap

* removed more meters, todo readd as traces

* docs

* fix: lint format and unit tests

* fixed otel under mpi. updated docs

* fix docs

* fix: Fix documentation and add missing python libs for running opentelemetry

* docs: Add explanations for opentelemetry while BSB is running

* updated docs

* fix: add mpi barrier in profiling test

---------

Co-authored-by: Robin De Schepper <robin@alexandria.sc>
Co-authored-by: drodarie <d.rodarie@gmail.com>

* feat!: Refactor voxel based partitions for atlases (#171)

* feat: transfer atlas-tools branch from bsb-core

* test: add unittests for NRRDDependencyNodes

* chore: add pragma no cover

* fix: excluded lines for coverage.

* chore: add pragma: nocover to abstract functions.

* test: add tests for partitions

* fix: file cleaning during unittest in parallel

* fix: removes get_voxelset as duplicate function to_voxel in Voxels class

- deals with the case where a partition does not have the particular density key attached to its data.

* fix: move voxel utility functions to voxels.py

* fix: click default value test for None values

see release notes for v8.3

* fix: examples for allen partitions, add tests for voxel resolution

change atlas_datasets to voxel_datasets

* feat: generalize voxels utility functions to list of voxels

- simplify VolumetricRotations using voxels functions and NrrdDependencyNode
- get rid of space_origin attribute which can cause out of bound issues for partitions.

* fix: add MPI barriers in tearDownClass

* feat: refactor voxel_datasets so that they are at the root of the configuration.

* fix: docstrings

* feat: rename voxel_datasets into files, make FileDependencyNode dynamic

* feat: allow reference attributes to be directly cast

* docs: Start to rewrite documentation on reference attributes

* fix: in case of an attribute soft reference, cast values that are not ready or references in __ref__

2nd pass on documentation on reference attributes
rename hard_reference into reference_only

* fix: Make ConfigurationReferenceListAttribute values stored in cfglist

move set type to __init__.
Add tests for setting element of ConfigurationReferenceListAttribute

* docs: Add documentation about files linking

- Refactor configuration files documentation (merge parsers)
- Add docs about new config root component `files`
- Specify union type for RegionalReference

* fix: add cfgreflist to store both references and values.

* fix: missing return and improve links in docs

* use a property to lazily evaluate cfgattr.type

* fix: Apply suggestions from code review

Co-authored-by: Robin De Schepper <robin.deschepper93@gmail.com>

* docs: implement review feedback

* fix: type_handler name extraction for UnionType

* fix: implement feedback from review

* fix: implement feedback from review

* fix: limit logs during unittests #182

- disable tqdm if bsb log level < 2
- fix missing flag for bsb-arbor iso-docs

* fix: reimplement is_ref for reference, make VoxelDatasetReference return a Node

try setting bsb verbosity flag in env for gha

* fix: try setting env vars via GITHUB_ENV

* fix: use report instead of prints for NonTTYTerminalListener

Remove NX_DAEMON as it has no impact on command nx run or nx affected

* fix: removes ConfigurationReferenceAttribute.is_reference_value and Reference.is_ref

revert change on NonTTYTerminalListener

* fix: remove ConfigurationReferenceListAttribute.get_ref_key

make ConfigurationReferenceAttribute.get_ref_key protected

* feat: add option to quiet logs

* docs: Add documentation on BSB options

* fix: first pass implementing reviewer feedback

* removed NoRefAttrSignal, added ReferenceLambdaError

* added ref lambda enhancement, tests, and docs

* fix: test_options and lint

* fix: autoconfig list attribute parsing for sphinx

add missing python packages version

* fix: voxel references call when removing from cfgdict and use reflist in to_voxels

---------

Co-authored-by: Robin De Schepper <robin@alexandria.sc>
Co-authored-by: Robin De Schepper <robin.deschepper93@gmail.com>

* feat: Add BSB examples (#186)

* docs: add yaml configurations snippets for the getting-started sections

* docs: add yaml configurations snippets for the neuron getting-started sections

* feat: the bsb simulate command will now create the output folder if provided. See #174

* fix: reference resolution when setting configuration

See #44, #175

* feat: isolate the getting-started examples in an independant folder.

* feat: add GHA for examples

* fix: examples.yml and re-add missing files.

* fix: re-add missing file.

* fix: examples.yml and getting-started_reconstruction.rst

* feat: isolate nest and neuron simulation examples.

* feat: isolate include_morphos examples and fix simulations

* feat: isolate writing_component examples

* feat: isolate atlas examples

* fix: add missing configuration and tests for writing_components

fix getting started unittests
fix bsb docs
move plot morpho to examples folder

* fix: unittests for examples, add noqa to avoid ruff fix

* fix: neuron simulation example

- add affinity parameter to speed up simulation.
- add warnings to VoxelIntersection in case of absence of matching labels #149
- add missing dependency to dbbs-catalogue
- add unittests
- exclude examples from pre-commit

* feat: add unittests for Allen example

- VoxelIntersection: add skips in case of absence of matching labels.
- add simple density file for tests
- add unittests
- move skip_tests for allen to bsb_test
- fix allen annotations download
- fix Readmes

* fix: add missing files

* feat: add unittests for include-morphologies examples

- fix atlas json config and readme

* fix: allen unittests, include_morphos docs

- revert skip of connectivity set creation for empty morphos

* fix: warning message

* feat: add examples as nx project

- move NEST installation bash script to devtools
- add unittests to NEST examples

* fix: examples gha and examples lint

* test: echo nest folder in GHA.

* fix: examples.yml

* fix: add nest folder variable in test_example script. add missing lib

* fix: install nest in a separate installation folder

Manually load the nest_vars before running the unittests
Remove manual run of examples GHA for each push

* feat: add example for cell labeling

* fix: change examples folders.

* feat: add morphology manipulation example.

- merge all morphology examples into one big script.
- change gha triggers

* feat: make examples bsb plugins + lint

* fix: labeling cells examples

- cleanup NEST build and installation folders in case of re-installation

* fix: neuromorpho url request

* feat: add nest repeated simulation example

* fix: remove nrnsub example

* fix: remove nrnsub example in docs

* fix: add mailing list in codemeta.json

* fix: remove unecessary unittest skips

* fix: dbbs-catalogue version

add store_active_config in nest-simulation example test

* fix: documentation for atlas and NEST repeated simulation

fix neuron example, bsb-core should be installed in parallel.

* fix: python neuron example

* fix: force store the active config during compile #189

pass lint and format
add missing lib for neuron examples
add flags for examples GHA.

* fix: case when NrrdVoxel.sources elem ref is not a string (dict or node)

* fix: make installation of libgsl global

* fix: skipIfOffline

* fix: add pragma: nocover for type checking

* fix: version of examples. Prevent examples to be released

* fix: bump gha versions, move NX_DAEMON to global env, use setup-node instead of direct install

* fix: re-add verify=False for NM selector

* fix: add lockfile to prevent concurrent installation of NEST on GHA

* fix: add exit to installation script for NEST on GHA

---------

Co-authored-by: Robin De Schepper <robin.deschepper93@gmail.com>
Co-authored-by: Robin De Schepper <robin@alexandria.sc>
Co-authored-by: DBBS Laboratory <neurocomp_dbbs@unipv.it>
Co-authored-by: Filippo <52816133+filimarc@users.noreply.github.com>
Co-authored-by: filimarc <filippo.marchetti@unipv.it>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants