Examples

Basic Usage

Neurodamus-py, as an application, is very similar to the HOC version, both run a simulaton fully unmanned guided by the BlueConfig. However, neurodamus-py does accept CLI options to define some parameters of the simulations.

Once installed, you should be able to find neurodamus in your path:

$ neurodamus
  Usage:
      neurodamus <BlueConfig> [options]
      neurodamus --help

Among the options you will find flags to tune run behavior, which was not possible in HOC.

Launching

Neurodamus-py explicitly depends on MPI libraries for parallel execution. Therefore please use “srun” or “mpiexec” to launch it, according to your platform. If you don’t, complicated error messages may show up. Please remember it.

Even though a neurodamus launcher is provided, for production runs we suggest using special instead. This way has proven to take advantage of optimized math libraries. We hope to bring the same advantages to the launcher script soon.

srun <srun params> special -mpi -python $NEURODAMUS_PYTHON/init.py <neurodamus params>

For detailed launching instructions on BB5, please visit the confluence page “Neurodamus” section “Neurodamus-py”.

Only build model, run later

The user has the possibility of creating the model to CoreNeuron independently of the run phase. Consider the case of a heavy simulation. It might be desirable to create the model and later attempt to run it with different parameters in a dedicated allocation.

Two options exist to control this behavior:
  • --build-model=[AUTO, ON, OFF] Defines whether the build phase should run. Default: AUTO

    • AUTO: build model if doesn’t exist and simulator is CoreNeuron

    • ON: always build and eventually overwrite the model

    • OFF: Don’t build the model. Simulation may fail to start

  • --simulate-model=[ON, OFF] Controls whether neurodamus will launch the simulation automatically. Default: ON

Resource estimation

Calculations

When running a simulation on bb5, the number of computing nodes needed depends on the number of cells being simulated. A rough(1) estimation is:

  • Each neuron can take ~ 20 - 25 MB memory for simulation.

  • Each node has ~ 360 GB x 1024 MB/GB = 368640 MB of memory

Hence each node can accommodate ~ 368640 / 25 = 14745 neurons.

In order to simulate faster, users can increase the number of nodes provided. HPC recommends ~ 15 neurons/core x 40 cores/node = 600 neurons/node. For example, for a circuit of 6000 cells, users can simulate it on a single node or 10 nodes.

The choice depends on the availability of nodes and how fast the results are expected, taking into consideration that the maximum number of nodes to request for each job is 720.

[1] Basic connectivity being considered. Depending on the connectivity and cells configurations (e.g. featuring heavier mechanisms) these figures can change significantly. This issue is being followed in https://bbpteam.epfl.ch/project/issues/browse/BBPBGLIB-556 For now we advise users to test jobs on a small scale before submitting a full-scale one.

Dry run mode

In order to obtain a more accurate estimation of the resources needed for a simulation, users can also run Neurodamus in dry run mode. This functionality is only available for SONATA circuits.

This mode will partially instantiate cells and synapses to get a statistical overview of the memory used but won’t run the actual simulation. The user can then check the estimated memory usage of the simulation as it’s printed on the terminal at the end of the execution. In a future update we will also integrate indications and suggestions on the number of tasks and nodes to use for that circuit based on the amount of memory used during the dry run.

The mode also provides detailed information on the memory usage of each cell metype, synapse type and the total estimated memory usage of the simulation, including the memory overhead dictated by loading of libraries and data structures.

The information on the cell memory usage is also automatically saved in a file called memory_usage.json in the working directory. This json file contains a dictionary with the memory usage of each cell metype in the circuit and is automatically loaded in any further execution of Neurodamus in dry run mode, in order to speed up the execution. In future we plan to also use this file to improve the load balance of actual simulations.

To run Neurodamus in dry run mode, the user can use the --dry-run flag when launching Neurodamus. For example:

neurodamus --configFile=BlueConfig --dry-run

Neurodamus for Developers

Neurodamus was designed to provide an easy Pythonic API while keeping the same concepts. Please see Module Reference

Disable / Enable connections during simulation

As an example, the user may want to enable and disable connections at different simulation times. (NOTE: this is only possible using the NEURON simulator. CoreNeuron simulations cannot be changed interactively).

from neurodamus import Neurodamus
from neurodamus.utils.logging import log_stage, log_verbose

nd = Neurodamus('BlueConfig')

log_stage('Run simulation!')
nd.solve(50)  # Until 50ms
nd.synapse_manager.disable_group(62977, 62698)
nd.solve()  # until end

Drop connections to not be simulated

Sometimes we may want to drop connections altogether. The user may completely avoid them from being instantiated in the simulator (compatible with CoreNeuron)

from neurodamus import Neurodamus
from neurodamus.utils.logging import log_stage, log_verbose

nd = Neurodamus('BlueConfig_for_remove', auto_init=False)

log_stage('Starting edge removal')
nd.synapse_manager.delete_group(62977, 62698)

nd.init()   # Initialize the simulator (needed because we set auto_init=False)
nd.run()    # Run all

Neurodamus as a High-Level API for neuron

A slightly different set of use cases is to provide users a powerful High-Level API for Neuron, to ease the life of manually setting up neuron networks. With this API, you can reduce the amount of code to setup models by as far as 5-fold (based on the next tutorials translation)

Example 1 - Neuron Tutorial Basic

Basic neuron usage on how to:

  • Build a single compartment neuron model

  • Add membrane mechanisms (such as ion currents)

  • Create stimuli and run simulations

  • Extend a single compartment model with dendrites

#!/usr/bin/env python
"""
Neuron tutorial I using the new HighLevel API. Original tutorial at
https://github.com/BlueBrain/SimulationTutorials/blob/master/CNS2017/NEURON/NEURON_intro.ipynb
"""
from neurodamus.core import Cell
from neurodamus.core import CurrentSource
from neurodamus.core import Neuron
from neurodamus.core import mechanisms


# Change v_init globally
# Alternatively v_init can be configured per simulation in run_sim(**kw)
Neuron.Simulation.v_init = -70


def test_tut1(quick=True):
    c = Cell.Builder.add_soma(60).create()
    hh = Cell.Mechanisms.HH(gkbar=0.0, gnabar=0.0, el=-70)
    hh.apply(c.soma)

    # clamp = StimuliSource.pulse(0.1, 50, delay=10).attach_to(c.soma)  # eqv. to Constant()
    CurrentSource.Constant(0.1, 50, 10).attach_to(c.soma)
    Neuron.run_sim(100, c.soma).plot()
    if quick:
        return

    # Execution with Active channels
    hh.gkbar = 0.01
    hh.gnabar = 0.2
    hh.apply(c.soma)
    sim = Neuron.run_sim(100, c.soma)
    # sim.run_continue(100)
    sim.plot()

    # Extending the model with dendrites
    c = (c.builder
         .add_dendrite("dend", 400, 9, diam=2, Ra=100)
         .add_dendrite("dend2", 400, 9, diam=2, Ra=100)
         .create())

    mechanisms.HH(el=-70, gl=5e-4, gkbar=.0, gnabar=.0).apply(c.dendrites)
    Neuron.run_sim(50, c.dendrites[0]).plot()

    Cell.show_topology()
    Neuron.h.psection(sec=c.dendrites[0])


if __name__ == "__main__":
    test_tut1(False)
    from six.moves import input
    input("Press enter to quit")

Example 2 - Neuron Tutorial synapses

def test_tut2():
    c = Cell(0, MORPHO)
    print("The morphology {} basal, {} apical, {} axonal sections.".format(
        len(c.dendrites), len(c.apical_dendrites), len(c.axons)))

    for sec in c.all:
        sec.nseg = 1 + 2 * int(sec.L / 40)
        sec.cm = 1
        sec.Ra = 100

    hh = mechanisms.HH(gkbar=.0, gnabar=.0, el=-70)
    hh.apply(c.all)
    hh.gkbar = 0.01
    hh.gnabar = 0.2
    hh.apply(c.soma)
    hh.gnabar = 0.25
    hh.apply(c.axons)

    clamp = CurrentSource.Constant(0.5, 200, 10).attach_to(c.soma)
    Neuron.run_sim(300, c.soma, v_init=-70).plot()

    # Part 2
    clamp.detach()

    stim = synapses.NetStim(5, 5, 20, 0)

    for sect in c.dendrites:
        sr = synapses.ExpSyn(sect(0.5))
        stim.connect_to(sr, weight=0.001)

    Neuron.run_sim(80, c.soma, v_init=-70).plot()

Neurodamus advanced simulation example

This is a more advanced example that instantiates a Neurodamus simulation step by step for a simple circuit. It creates a Node object and it takes care of doing the following:

  • Loads targets

  • Computes Load Balancing

  • Instantiates cells

  • Instantiates synapses and gap junctions

  • Enables stimulus

  • Enables modifications

  • Enables reports

  • Runs simulation

  • Dumps spikes to files

  • Cleans up the simulated model

def test_node_run(trace=False):
    """Node is more of a low-level class, where all initialization steps are manual
    """
    setup_logging(DEFAULT_LOG_LEVEL)
    if trace:
        # Some additional logging is available at special level 5
        print("TRACE mode is ON")
        logging.root.setLevel(TRACE_LOG_LEVEL)

    node = Node(RECIPE_FILE)
    node.load_targets()
    node.compute_load_balance()
    node.create_cells()
    node.execute_neuron_configures()

    logging.info("Create connections")
    node.create_synapses()

    logging.info("Enable Stimulus")
    node.enable_stimulus()

    logging.info("Enable Modifications")
    node.enable_modifications()

    if trace:
        logging.info("Dumping config")
        Nd.stdinit()
        node.dump_circuit_config("")

    logging.info("Enable Reports")
    node.enable_reports()

    logging.info("Run")
    node.run_all()

    logging.info("Simulation finished.")
    node.cleanup()

Source

examples.rst