Skip to main content

Recurrent Neural Blackboard Architecture - a simulation framework for neuro-cognitive modelling.

Project description

RNBA — Replication of the Recurrent Neural Blackboard Architecture

In the paper Sentences as connection paths: A neural language architecture of sentence structure in the brain (2022), van der Velde presents a proposal for language representation in the brain. The model is a considerable extension of an earlier one (van der Velde and de Kamps, 2006). The simulations supporting the 2022 paper have been made public (van der Velde, 2025). This project is a reimplementation of these simulations, with the aims of providing a pedagogical introduction to the paper and providing improved visualization of both the architecture and its dynamics.

The simulations are represented as is. The design decisions behind the original simulations are not questioned here, but where issues arise that may confuse the replication, they will be discussed.

Purpose of this Repository

The simulations that were made available on Zenodo (van der Velde, 2025) serve the important purpose of making the simulations of van der Velde (2022) reproducible, but they are not very transparent in exposing the computational elements of the RNBA. The simulator presented here serves a dual purpose:

  • To serve as departure point for extensions of the RNBA architecture that are investigated at the University of Leeds
  • To make the computational structure of the RNBA architecture more transparent than shown in the Zenodo repository, so that new researchers can get up to speed more quickly. To this end, there are a number of Jupyter notebooks in the examples/ folder.

Installation

For most users:

pip install rnba

This installs the Python package and a precompiled C++ simulator (rnba-sim) — no compiler needed. Wheels are published for Linux (x86_64, aarch64), macOS (Intel, Apple Silicon) and Windows.

For development, clone the repository and install editable. Because pip install also builds the C++ simulator from source, this requires CMake ≥ 3.15 and a C++17 compiler in addition to Python ≥ 3.8:

git clone https://github.com/dekamps/RNBACode.git
cd RNBACode
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

Plotting and visualization extras: pip install "rnba[viz]" (matplotlib + graphviz bindings).

Running Simulations

This is the typical use of the package. A simulation needs:

  1. an architecture file describing the complete neural blackboard (e.g. tests/RNBA_arch_SGall_SNB15.txt);
  2. an instruction file giving the timings at which populations are switched on and off — word inputs, gating populations, etc. Both instruction formats (QA and SGall) are accepted and auto-detected; they are fully documented in docs/instruction-file-formats.md;
  3. optionally a bindings file, which pre-stores bindings in the network, emulating sentences that were read into the blackboard previously (e.g. tests/RNBA_SGall_SNB15_Bindings_Sentence_3NVN.txt).

The output is a CSV with one row per timestep (h = 0.1 ms) and one column per population.

Python simulator: rnba-run

rnba-run \
  --architecture tests/RNBA_arch_SGall_SNB15.txt \
  --instruction  tests/QA_3NVN_O_success.txt \
  --bindings     tests/RNBA_SGall_SNB15_Bindings_Sentence_3NVN.txt \
  --output       qa_trace.csv \
  --output-row-map qa_row_map.csv \
  --output-named

Useful options:

  • Duration is derived automatically from the instruction schedule (plus --tail-steps, default 500). Override with --t-end MS or --n-steps N; values that would truncate the schedule are rejected.
  • --output-row-map FILE writes the row-index ↔ pop_id mapping needed by the plotting tools.
  • --output-named additionally writes the trace with human-readable pop_id[row] column headers (<output>_named.csv).
  • --output-inputs FILE writes the external input traces.
  • --engine state_update (default, mirrors the C++ solver) or --engine odeint_chunks.

(In a source checkout without installation, use python -m rnba.simulation with the same arguments.)

C++ simulator: rnba-sim

The C++ simulator is functionally equivalent and considerably faster. It reads a JSON simulation contract instead of the architecture text file; generate one first:

python cpp-sim/tools/export_network.py \
  --load-from tests/RNBA_arch_SGall_SNB15.txt \
  --output snb15_contract.json

(Ready-made contracts for common configurations are committed under cpp-sim/data/.)

Then run, with the same instruction/bindings files as the Python simulator:

rnba-sim \
  --model         snb15_contract.json \
  --instructions  tests/QA_3NVN_O_success.txt \
  --bindings      tests/RNBA_SGall_SNB15_Bindings_Sentence_3NVN.txt \
  --t-end         180.0 \
  --output        qa_trace_cpp.csv \
  --output-row-map qa_row_map.csv

rnba-sim --help documents all options. Both simulators produce the same CSV format, so the inspection tools below work with either.

Inspecting Results

Activation plots for named populations: rnba-plot

Populations are usually selected by their descriptive pop_id (see naming conventions below). Given a trace CSV and the row map:

# All rows whose pop_id is MA_Word_A1
rnba-plot --csv qa_trace.csv --row-map qa_row_map.csv \
          --pop MA_Word_A1 --out word_A1.png

# A specific population instance, and a raw row index
rnba-plot --csv qa_trace.csv --row-map qa_row_map.csv \
          --pop 'GC_start_G1[158]' --pop 42 --out mixed.png

--pop may be repeated; --architecture arch.txt can replace --row-map; on a *_named.csv written by rnba-run --output-named, no mapping file is needed at all. --t-min/--t-max restrict the time window. Requires pip install "rnba[viz]".

Activity-flow video

The schematic activity-flow renderer overlays simulation traces on the SNB15 schematic and can render a video (requires ffmpeg):

python -m rnba.visualize_activity_flow \
  --architecture tests/RNBA_arch_SGall_SNB15.txt \
  --trace-csv    qa_trace.csv \
  --inputs-csv   qa_inputs.csv \
  --out-dir      activity_flow_out \
  --render-video \
  --frames-dir   activity_flow_out/frames \
  --video-out    qa_activity.mp4 \
  --fps 25 --step-ms 1.0

See python -m rnba.visualize_activity_flow --help for the full option set (codec, styling, frame selection).

Quick Start: Replicating the QA Simulation

The file examples/example_qa_simulation.py is a faithful replication of the Zenodo simulation performed in the original RNBA24_sim_QA_3NVN.py (kept in legacy/). It takes roughly 15 minutes to run. The workflow:

  1. Read the complete blackboard architecture from tests/RNBA_arch_SGall_SNB15.txt.
  2. Apply the bindings file tests/RNBA_SGall_SNB15_Bindings_Sentence_3NVN.txt, which pre-stores bindings in the network, emulating sentences previously read into the network.
  3. Read the instruction files tests/QA_3NVN_O_success.txt and tests/QA_3NVN_O_fail.txt (QA format).
  4. Run both simulations.
  5. Inspect the results in examples/example_qa_output/: qa_3nvn_word_populations_success.png and qa_3nvn_word_populations_fail.png replicate Fig. 4 in van der Velde (2026).

Examples

See the examples/ folder for Jupyter notebooks demonstrating RNBA usage:

  • Example_01_WIlsonCowan.ipynb: Two-population excitatory/inhibitory (E/I) circuit demonstrating Wilson-Cowan dynamics with external input.
  • Example_02_BasicCircuits.ipynb: Complete RNBA circuit architecture including Wilson-Cowan populations, Working Memory, Gating circuits, and Binding circuits. Demonstrates the four fundamental circuit types from the original simulations.

For further examples, see the README.md in the examples folder.

pip install -e ".[dev]"
jupyter notebook examples/

Each notebook is self-contained and can be executed end-to-end.

Programmatic Architecture Build

The repository includes a script that programmatically rebuilds the architecture from the analysis text file:

python examples/example_network_creation.py

This script:

  • Loads examples/RNBA_arch_SGall_SNB15.txt
  • Builds a Network using the current core primitives/wrappers as family coverage references
  • Creates network nodes with canonical runtime IDs (row indices as strings)
  • Tracks architecture row IDs (idx) to descriptive pop_id labels
  • Reconstructs connectivity from the text specification and reports summary counts

Node Naming Conventions (row_id vs pop_id)

RNBA uses two complementary naming schemes:

  • Canonical runtime ID (row_id): for normal populations, the node name is the row index as a string (e.g., "158"). This is the stable, unique ID used by load_architecture and runtime networks.
  • Descriptive label (pop_id): a human-readable role name such as GC_start_G1, SA_WM_SG1Verb_B9, etc. These repeat across rows, so pop_id alone is not unique for normal populations.
  • Unique descriptive label: pop_id[row_id] (e.g., GC_start_G1[158]) is unique and readable; this is what rnba-run --output-named and the converter emit when relabeling traces.
  • External inputs: their runtime name is pop_id (these are unique).

Conversion helpers:

  • rnba.converters.architecture.parse_architecture_txt + build_row_index_maprow_map[idx].pop_id
  • rnba.converters.architecture.relabel_trace_headerspop_id[row_id] labels (CLI: rnba-arch-convert --relabel-trace)
  • After load_architecture, net.population_metadata[str(idx)]["pop_id"] yields the label for a node.

Documentation

Project documentation lives in the docs/ folder:

  • Instruction file formats (QA and SGall): docs/instruction-file-formats.md
  • Analysis: docs/analysis/
  • Design notes: docs/design/
  • Circuit library design and implementation status: docs/design/CIRCUIT_LIBRARY_DESIGN.md

Circuit Factory Functions

The circuit library provides factory functions that create topologically identical circuits with different template names. This naming convention supports explicit traceability to roles in RNBA_arch_SGall_SNB15.txt.

Core topologies:

  • create_gating_circuit / create_inhibgate_circuit / create_gate_sg_cm_circuit / create_gate_sg_w_circuit / create_gate_lma_w_pos_circuit / create_linked_bgate_dtoh_circuit — all gating topology (differ only in template name)
  • create_wm_circuit — working memory topology
  • create_bgate_circuit — binding gate topology
  • create_linked_bgate_circuit — linked binding gate topology
  • create_sg_core_circuit — SG competition/bridge core topology

Naming convention: When building the full architecture programmatically (as in example_network_creation.py), circuit names are deliberately chosen to match their architectural roles. For example:

  • A gate intended for SG→CM binding uses create_gate_sg_cm_circuit() to register with template name "Gate_SG_CM_circuit"
  • A gate intended for SG→W binding uses create_gate_sg_w_circuit() to register with template name "Gate_SG_W_circuit"

This makes instantiated circuit names traceable to specific roles in the architecture specification.

Example:

from rnba.circuits import create_gating_circuit, create_gate_sg_cm_circuit
from rnba.network import Network

net = Network()

# For a generic gate role
net.register_circuit(create_gating_circuit(w_internal=0.2))

# For explicit SG→CM role (same topology, different template name for traceability)
net.register_circuit(create_gate_sg_cm_circuit(w_internal=0.2))

# Both create instances with names matching their architectural intent
instance1 = net.instantiate_circuit("Gating_circuit", "gate_0")
instance2 = net.instantiate_circuit("Gate_SG_CM_circuit", "sg_cm_gate_0")

Network Visualization

The RNBA package includes a graphviz-based visualization module (rnba.visualize) that renders networks as diagrams. This is useful for understanding network architecture and debugging connectivity.

Features:

  • Detailed view: Visualizes all nodes (populations) and connections in your network
  • Abstract view: Shows circuits as single boxes (aggregate view of circuit-level architecture)
  • Color-codes nodes by type (red=excitatory, blue=inhibitory, gray=other)
  • Shows connection weights and direction
  • Groups nodes by circuit instance with light gray boxes
  • Supports multiple layout directions (top-to-bottom, left-to-right)
  • Exports to PNG, SVG, PDF, and other formats

Quick start:

# Install visualization dependencies
pip install -e ".[viz]"

# Requires graphviz system package:
# macOS: brew install graphviz
# Ubuntu/Debian: sudo apt-get install graphviz
# Windows: https://graphviz.org/download/

# Run the demo to see both visualization modes
python examples/demo_network_visualization.py

This generates PNG diagrams of the example_2 network in your current directory (both detailed and abstract views).

Usage in your code:

from rnba.visualize import visualize_network

# Detailed view (all nodes and populations)
visualize_network(
    network=my_network,
    output_file="my_network_detailed",
    format="png",
    show_weights=True,
    group_by_circuit=True,
    rankdir="TB"  # "TB" for top-to-bottom, "LR" for left-to-right
)

# Abstract view (circuits as boxes)
visualize_network(
    network=my_network,
    output_file="my_network_abstract",
    format="png",
    show_weights=True,
    abstract_circuits=True,  # <-- Enable abstract circuit-level view
    rankdir="TB"
)

When to use each view:

  • Detailed: Debugging internal circuit connectivity, understanding population dynamics
  • Abstract: Getting high-level overview of circuit architecture, understanding inter-circuit communication patterns

See tests/test_visualize.py for additional examples.

Full-Scale Architecture Visualisation

The graphviz module above is suited to small hand-built networks and circuit diagrams. For the full RNBA architecture (16,000–32,000 populations), a separate pipeline exists that uses GEXF + ForceAtlas 2 (Gephi) + matplotlib.

The complete pipeline — including all automated steps, the manual Gephi layout step, FA2 settings, output file descriptions, and instructions for what to do when the architecture changes — is documented and driven by:

bash examples/visualize_architecture.sh

That script is the authoritative runbook for full-scale network visualisation. It produces:

  • Grey GEXF files for import into Gephi (automated)
  • Coloured circle GEXF files with external populations on a ring (automated, requires committed FA2 exports)
  • Rendered PNGs at 300 dpi for both the 16k and 32k E/I layouts

SNB15 Schematic Visualisation (Collapsed Motif View)

The repository also includes a standalone schematic renderer:

  • rnba/schematic_visualization.py

This script produces the compact SNB15 motif-style figures used during gate-marker and linked-binding visual checks.

From the repository root, use these exact commands:

Generate the 4-row view:

python -m rnba.schematic_visualization --first-rows 4 --formats png --basename word_assemblies_schematic_first4

Generate the full 15-row view:

python -m rnba.schematic_visualization --formats png --basename word_assemblies_schematic_full15

Reference Plots (Canonical Commands)

For future reproducibility, these are the two exact reference renders.

  1. Colour plot with SG competition in full mode:
source .venv/bin/activate && python -m rnba.schematic_visualization --show-control-nodes --show-output-path --show-sg-competition --sg-competition-mode full --formats pdf --basename word_assemblies_schematic_controls_flow_option3a_interleaved_v21_sgcomp_full

Expected output file:

  • word_assemblies_schematic_controls_flow_option3a_interleaved_v21_sgcomp_full.pdf
  1. Dark-mode plot without SG competition:
source .venv/bin/activate && python -m rnba.schematic_visualization --show-control-nodes --show-output-path --activity-flow-theme --formats pdf --basename word_assemblies_schematic_controls_flow_dark_option3a_interleaved_v22_no_sgcomp

Expected output file:

  • word_assemblies_schematic_controls_flow_dark_option3a_interleaved_v22_no_sgcomp.pdf

Development

Run tests:

# All tests (unit + integration)
pytest tests/ -v

# Unit tests only (skip slower integration tests)
pytest tests/ -m "not integration" -v

# Integration tests only
pytest tests/integration/ -v

C++ simulator development build (separate from the pip build):

cmake -B cpp-sim/build cpp-sim
cmake --build cpp-sim/build -j
ctest --test-dir cpp-sim/build

Experiments folder: The experiments/ directory (not version-controlled) is a scratch space for developing new use cases and prototypes before promoting polished examples to the examples/ folder. Legacy pre-package scripts are preserved in legacy/.

License: MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rnba-0.2.0.tar.gz (16.0 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rnba-0.2.0-py3-none-win_amd64.whl (180.4 kB view details)

Uploaded Python 3Windows x86-64

rnba-0.2.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (186.2 kB view details)

Uploaded Python 3manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

rnba-0.2.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (176.8 kB view details)

Uploaded Python 3manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

rnba-0.2.0-py3-none-macosx_11_0_arm64.whl (167.2 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

rnba-0.2.0-py3-none-macosx_10_15_x86_64.whl (176.0 kB view details)

Uploaded Python 3macOS 10.15+ x86-64

File details

Details for the file rnba-0.2.0.tar.gz.

File metadata

  • Download URL: rnba-0.2.0.tar.gz
  • Upload date:
  • Size: 16.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rnba-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f4fa813cf79906d2e5454968755d49e7282f6e5c8540431b2e6e09e74e28e6e0
MD5 a0b2a3fc392aaa13ecf49c2a3e14874b
BLAKE2b-256 1b30143af2934cc3ec7ed1b0c5fffbd68e57356d6e3f49c58912a6a450cf5dd8

See more details on using hashes here.

Provenance

The following attestation bundles were made for rnba-0.2.0.tar.gz:

Publisher: wheels.yml on dekamps/RNBACode

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rnba-0.2.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: rnba-0.2.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 180.4 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rnba-0.2.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 24669a827d0dc9a840c9d0f3baf19cfaa51be0bf240001a22e1953053ba576f4
MD5 d2f77b593f0ecc465e4715cbfd33add5
BLAKE2b-256 d88a5ca8bcd52feb772790c0c552fca6513f19dc57cd713aa2e7e41a2d5edb2a

See more details on using hashes here.

Provenance

The following attestation bundles were made for rnba-0.2.0-py3-none-win_amd64.whl:

Publisher: wheels.yml on dekamps/RNBACode

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rnba-0.2.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for rnba-0.2.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c81ef4a06cb26aad51161b9d731ac50c42d1b1b66c0de968f8e1316240efbc03
MD5 7d7cf2fc0e37be96fdeb4211bac5a72c
BLAKE2b-256 c31aaeba07e7a99418934f3bd61a132d74ce5b2b294cb2c81ce64da1deedad36

See more details on using hashes here.

Provenance

The following attestation bundles were made for rnba-0.2.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on dekamps/RNBACode

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rnba-0.2.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for rnba-0.2.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 06b27be10e2fd7691b3ad97dcbcc9bb9c8588b232b074104f5fd8a4d590cfb28
MD5 d2a3bd2929681eb3210fa076f3a5fa4a
BLAKE2b-256 0162d254be4cabae9dba95eb288805b5a00c1ddaae951bab3f49fcea361cd7de

See more details on using hashes here.

Provenance

The following attestation bundles were made for rnba-0.2.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: wheels.yml on dekamps/RNBACode

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rnba-0.2.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: rnba-0.2.0-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 167.2 kB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rnba-0.2.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 04acde0afd3f5e76570691e803836fb3cf060376c129a276fe5a985f646d9a8d
MD5 b0edbfd4770ded5be86e9e876b959d25
BLAKE2b-256 f1309db2f5a178d3ab9a11e32421397c28a13537026ad795897675b81d1fd1b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for rnba-0.2.0-py3-none-macosx_11_0_arm64.whl:

Publisher: wheels.yml on dekamps/RNBACode

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rnba-0.2.0-py3-none-macosx_10_15_x86_64.whl.

File metadata

  • Download URL: rnba-0.2.0-py3-none-macosx_10_15_x86_64.whl
  • Upload date:
  • Size: 176.0 kB
  • Tags: Python 3, macOS 10.15+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rnba-0.2.0-py3-none-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 ecb2865c8d6d89e9a006ad917fa615431b2a14c11fb28a08f1117d053adf43b8
MD5 571ca66e608d60b8767df9402f849fd5
BLAKE2b-256 3e5dab14260515b16412ec43347bbd4a41822cb96a560dd8e7d45283d5b91ff6

See more details on using hashes here.

Provenance

The following attestation bundles were made for rnba-0.2.0-py3-none-macosx_10_15_x86_64.whl:

Publisher: wheels.yml on dekamps/RNBACode

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page