rnba 0.2.2__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rnba-0.2.2 → rnba-0.2.3}/.gitignore +7 -0
- {rnba-0.2.2 → rnba-0.2.3}/PKG-INFO +2 -1
- {rnba-0.2.2 → rnba-0.2.3}/README.md +1 -0
- rnba-0.2.3/docs/activity-flow-colour-coding.md +344 -0
- rnba-0.2.3/docs/simulation-and-visualization-workflow.tex +208 -0
- rnba-0.2.3/docs/snb15-circuits-and-links.md +240 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/snb15_population_categories.md +1 -1
- {rnba-0.2.2 → rnba-0.2.3}/pyproject.toml +1 -1
- {rnba-0.2.2 → rnba-0.2.3}/rnba/__init__.py +1 -1
- {rnba-0.2.2 → rnba-0.2.3}/rnba/visualize_activity_flow.py +9 -6
- {rnba-0.2.2 → rnba-0.2.3}/LICENSE +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/NBA24_QA_sentence_input.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/NBA_SGall_sentence_input.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/NBA_read_architecture.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/.gitignore +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/CMakeLists.txt +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/CMakePresets.json +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/README.md +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/data/README.md +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/data/example_snb1_contract.json +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/data/model_smoke_contract.json +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/data/network.schema.json +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/data/snb15_contract.json +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/data/snb20_contract.json +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/include/model.hpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/include/output.hpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/include/parser.hpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/include/simulator.hpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/include/sparse_matrix.hpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/src/main.cpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/src/model.cpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/src/output.cpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/src/parser.cpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/src/simulator.cpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/src/sparse_matrix.cpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tests/CMakeLists.txt +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tests/data/model_smoke_contract.json +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tests/data/snb20_contract.json +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tests/test_golden.cpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tests/test_parser.cpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tests/test_simulator.cpp +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tools/export_network.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tools/plot_cpp_qa.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tools/plot_ncv_output.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/cpp-sim/tools/plot_trace_comparison.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/analysis/QA_GENERATED_SIMULATION_WALKTHROUGH.md +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/analysis/README.md +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/analysis/collapse_verification.md +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/analysis/rowviz.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/analysis/schematic_inclusion_matrix.md +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/analysis/visualize_core_circuits.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/bindings-file-format.md +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/instruction-file-formats.md +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/docs/templates/schematic_template_manifest.md +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/Collapsed_network_force.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/Collapsed_network_force_2026-05-22_noring_v1.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/Example_01_WIlsonCowan.ipynb +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/Example_02_BasicCircuits.ipynb +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/collapse_bgates.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/colour_gexf.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/demo_network_visualization.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/example_2.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/example_3.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/example_clamp.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/example_nCV_generated.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/example_network_creation.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/example_qa_create_network.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/example_qa_generated.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/example_qa_simulation.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_circle_16k.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_circle_ei_32k.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_ei_grey_32k.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_ei_grey_seeded_32k.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_force_16k.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_force_ei_32k.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_grey_16k.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_sfdp.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_sfdp_ei.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_sfdp_grey.gephi +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_network_sfdp_rows12.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/full_scale_sfdp_visualization.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/gexf_roles.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/layout_rows.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/render_collapsed.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/render_gexf.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/rnba_roles_row1.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/rnba_roles_snb15.gexf +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/row_visualization.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/seed_circle_ext.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/seed_ei_gexf.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/examples/visualize_architecture.sh +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/_sim.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/architecture.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/blackboard.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/circuit.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/circuits/__init__.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/circuits/core.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/cli.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/constants.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/converters/__init__.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/converters/architecture.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/inputs.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/network.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/nodes.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/plotting.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/schematic_visualization.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/simulation.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/rnba/visualize.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/QA_3NVN_O_fail.txt +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/QA_3NVN_O_success.txt +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/RNBA_SGall_SNB15_Bindings_Sentence_3NVN.txt +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/RNBA_arch_SGall_SNB15.txt +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/RNBA_arch_SGall_SNB20.txt +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/RNBA_arch_SGall_SNB30.txt +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/Sentence_2CV.txt +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/conftest.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/integration/__init__.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/integration/test_architecture_vs_gexf.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_architecture.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_basic.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_blackboard.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_circuit.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_circuits.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_clamp_integration.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_cpp_ncv_golden.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_instruction_unified.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_instruction_window_semantics.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_network.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_nodes.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_rnba_arch_converter.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_rnba_simulation_launcher.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_simulation_engines.py +0 -0
- {rnba-0.2.2 → rnba-0.2.3}/tests/test_visualize.py +0 -0
|
@@ -62,6 +62,13 @@ bla.py
|
|
|
62
62
|
/*.pdf
|
|
63
63
|
examples/*.pdf
|
|
64
64
|
|
|
65
|
+
# LaTeX build artifacts from docs/ sources (docs/templates PDFs stay tracked;
|
|
66
|
+
# these globs match the docs/ root only, not subdirectories)
|
|
67
|
+
docs/*.aux
|
|
68
|
+
docs/*.log
|
|
69
|
+
docs/*.out
|
|
70
|
+
docs/simulation-and-visualization-workflow.pdf
|
|
71
|
+
|
|
65
72
|
# Local experiment outputs in tracked_experiments (only the scripts and
|
|
66
73
|
# sentence inputs there are tracked)
|
|
67
74
|
tracked_experiments/activity_flow_*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: rnba
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Recurrent Neural Blackboard Architecture - a simulation framework for neuro-cognitive modelling.
|
|
5
5
|
Author-Email: RNBA Contributors <m.dekamps@leeds.ac.uk>
|
|
6
6
|
License: MIT
|
|
@@ -226,6 +226,7 @@ RNBA uses **two complementary naming schemes**:
|
|
|
226
226
|
## Documentation
|
|
227
227
|
|
|
228
228
|
Project documentation lives in the docs/ folder:
|
|
229
|
+
- Simulation-to-video workflow (LaTeX): [docs/simulation-and-visualization-workflow.tex](docs/simulation-and-visualization-workflow.tex)
|
|
229
230
|
- Instruction file format (unified; legacy QA and SGall dialects): [docs/instruction-file-formats.md](docs/instruction-file-formats.md)
|
|
230
231
|
- Bindings file format: [docs/bindings-file-format.md](docs/bindings-file-format.md)
|
|
231
232
|
- Analysis: [docs/analysis/](docs/analysis/)
|
|
@@ -189,6 +189,7 @@ RNBA uses **two complementary naming schemes**:
|
|
|
189
189
|
## Documentation
|
|
190
190
|
|
|
191
191
|
Project documentation lives in the docs/ folder:
|
|
192
|
+
- Simulation-to-video workflow (LaTeX): [docs/simulation-and-visualization-workflow.tex](docs/simulation-and-visualization-workflow.tex)
|
|
192
193
|
- Instruction file format (unified; legacy QA and SGall dialects): [docs/instruction-file-formats.md](docs/instruction-file-formats.md)
|
|
193
194
|
- Bindings file format: [docs/bindings-file-format.md](docs/bindings-file-format.md)
|
|
194
195
|
- Analysis: [docs/analysis/](docs/analysis/)
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# Activity-flow video: colour coding
|
|
2
|
+
|
|
3
|
+
How `rnba.visualize_activity_flow` colours the compressed schematic, what
|
|
4
|
+
that colouring expresses in terms of the published RNBA model, and where
|
|
5
|
+
the implementation currently diverges.
|
|
6
|
+
|
|
7
|
+
The reference is van der Velde, *The recursive neural blackboard
|
|
8
|
+
architecture for combinatorial sentence structures in the brain*
|
|
9
|
+
(`FvdV-RNBA26-article.pdf`) and its Supplementary Material
|
|
10
|
+
(`FvdV-RNBA26-SM.pdf`, cited below as **SM**).
|
|
11
|
+
|
|
12
|
+
## 1. The compressed representation
|
|
13
|
+
|
|
14
|
+
The video does not draw one marker per population. It draws a *template*
|
|
15
|
+
schematic in which each marker stands for a circuit — several populations
|
|
16
|
+
collapsed into one symbol. Each symbol therefore needs a population
|
|
17
|
+
chosen to speak for it:
|
|
18
|
+
|
|
19
|
+
- the **activity representative** — the population whose trace stands for
|
|
20
|
+
the circuit's activity. For gating circuits this is the gate output,
|
|
21
|
+
`GC_gate_G4`.
|
|
22
|
+
- the **WM representative** — the circuit's working-memory pair,
|
|
23
|
+
`WM1_Apop` / `WM2_Bpop`. Some circuits have one; most do not.
|
|
24
|
+
|
|
25
|
+
SM A.2: a WM population is *simulated* as two interacting populations A
|
|
26
|
+
and B, of which "population A is seen and referred to as the WM
|
|
27
|
+
population, because it alone receives input activity from the rest of the
|
|
28
|
+
architecture and generates excitatory output"; the activities of A and B
|
|
29
|
+
"are summarized as WM activity in the simulations."
|
|
30
|
+
|
|
31
|
+
## 2. Semantics, derived from SM I.1
|
|
32
|
+
|
|
33
|
+
SM I.1 partitions every SNB population into three categories:
|
|
34
|
+
|
|
35
|
+
- **Gating** — all populations in gating and linked-binding circuits,
|
|
36
|
+
*except* the WM populations in the latter.
|
|
37
|
+
- **WM** — all A and B populations forming WM populations.
|
|
38
|
+
- **Other** — all remaining SNB populations, "such as the word
|
|
39
|
+
populations".
|
|
40
|
+
|
|
41
|
+
This is the model's own distinction between **control** and **stored
|
|
42
|
+
structure**, and it is load-bearing in the paper: Figures 4B/4C plot
|
|
43
|
+
Gating, WM and Other as separate curves, and the central result is that
|
|
44
|
+
Total activity "is dominated by Gating, related to the control of
|
|
45
|
+
sentence processing," while the contribution of WM — "related to storing
|
|
46
|
+
a sentence/constituent structure" — is "small and 'flat'."
|
|
47
|
+
|
|
48
|
+
**The colour scheme is the spatial analogue of that plot:**
|
|
49
|
+
|
|
50
|
+
| Colour | Meaning | SM I.1 category |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| **Red** | control activity — a gate is passing signal | Gating |
|
|
53
|
+
| **Yellow** | stored structure — a WM is latched | WM |
|
|
54
|
+
| **Orange** | both at once | Gating + WM |
|
|
55
|
+
| Grey | below threshold; inactive baseline | — |
|
|
56
|
+
|
|
57
|
+
Yellow is the signature of persistence. Per SM D.1.1, an LMA *is* a WM
|
|
58
|
+
population and "remains active until a new LMA of the same type is
|
|
59
|
+
activated" — so a latched LMA should read yellow for as long as it holds
|
|
60
|
+
its content.
|
|
61
|
+
|
|
62
|
+
### Category assignment is mechanical
|
|
63
|
+
|
|
64
|
+
A population's category follows from its `pop_id` alone:
|
|
65
|
+
|
|
66
|
+
| `pop_id` | Category |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| `WM1_Apop`, `WM2_Bpop` | WM |
|
|
69
|
+
| `GC_start_G1`, `GC_disinhibition_G2`, `GC_inhibition_G3`, `GC_gate_G4` | Gating |
|
|
70
|
+
| anything else | Other |
|
|
71
|
+
|
|
72
|
+
Applying that rule to `RNBA_arch_SGall_SNB15.txt` reproduces SM table S15
|
|
73
|
+
exactly:
|
|
74
|
+
|
|
75
|
+
| Category | This repo | SM table S15 (SNB15) |
|
|
76
|
+
| --- | ---: | ---: |
|
|
77
|
+
| Gating | 10980 | 10980 ✓ |
|
|
78
|
+
| WM | 2970 | 2970 ✓ |
|
|
79
|
+
| Other | 2190 | 2190 ✓ |
|
|
80
|
+
| Total | 16140 | 16140 ✓ |
|
|
81
|
+
| External | 158 | 158 ✓ |
|
|
82
|
+
| Total in simulation | 16298 | 16298 ✓ |
|
|
83
|
+
|
|
84
|
+
(16298 is also the `lenlist` in the architecture file header.) The 2970 WM
|
|
85
|
+
populations are **1485 WM pairs**.
|
|
86
|
+
|
|
87
|
+
### Blue
|
|
88
|
+
|
|
89
|
+
`WORD_INHIB` symbols and the single global competition node take a
|
|
90
|
+
separate branch and render blue. This has no counterpart in SM I.1 —
|
|
91
|
+
their representatives (`MA_Word_inhib_A1a`) are **Other** populations. See
|
|
92
|
+
§6, finding D.
|
|
93
|
+
|
|
94
|
+
## 3. As implemented
|
|
95
|
+
|
|
96
|
+
Each symbol gets two independent intensities per frame.
|
|
97
|
+
|
|
98
|
+
**Activity representative** — `_value_for_mapping`
|
|
99
|
+
(`rnba/visualize_activity_flow.py:1152`): the `primary_index` row, or
|
|
100
|
+
`max(primary, secondary)` when the mapping mode is not `direct`.
|
|
101
|
+
|
|
102
|
+
**WM representative** — `_value_for_wm` (`:1160`): `max(wm1, wm2)`, or
|
|
103
|
+
`0.0` when either index is `-1`. (SM A.2 says the two are "summarized";
|
|
104
|
+
the code takes the max.)
|
|
105
|
+
|
|
106
|
+
Both pass through `_normalize_activity` (`:1166`): values below
|
|
107
|
+
`--activation-threshold` (default `1.0`) clamp to zero, the remainder
|
|
108
|
+
rescales against `--vmax` (default `100.0`) and is raised to
|
|
109
|
+
`--activation-gamma` (default `0.7`).
|
|
110
|
+
|
|
111
|
+
The two are decomposed (`:1418-1421`) and mixed (`:1432-1435`):
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
overlap = min(t_rep, t_wm)
|
|
115
|
+
rep_only = t_rep - overlap
|
|
116
|
+
wm_only = t_wm - overlap
|
|
117
|
+
|
|
118
|
+
r = 1.00 * rep_only + 1.00 * overlap + 0.95 * wm_only
|
|
119
|
+
g = 0.04 * rep_only + 0.58 * overlap + 0.95 * wm_only
|
|
120
|
+
b = 0.06 # constant
|
|
121
|
+
alpha = 0.40 + 0.60 * max(t_rep, t_wm)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The explicit decomposition exists so overlap reads orange rather than
|
|
125
|
+
collapsing to yellow. Blue is a separate branch (`:1424-1429`) using the
|
|
126
|
+
activity representative only. Marker size scales with
|
|
127
|
+
`max(t_rep, t_wm)` (`:1440`); `WORD` symbols draw at double size.
|
|
128
|
+
|
|
129
|
+
**Readability.** `b` is pinned at `0.06`, so red, orange and yellow differ
|
|
130
|
+
*only in the green channel*. At low `--dpi` and small markers they are
|
|
131
|
+
easy to confuse, and a latched-but-dim symbol is both faint (alpha floor
|
|
132
|
+
`0.40`) and colour-ambiguous. `--first-rows N` helps: it scales overlay
|
|
133
|
+
markers 3x (`:1296`).
|
|
134
|
+
|
|
135
|
+
> The constants above were hand-tuned, not derived. The commit that
|
|
136
|
+
> established the current rendering path (`82691ab`) says "Colors and
|
|
137
|
+
> transparency still need further tuning." Sections 1–2 are the
|
|
138
|
+
> specification; §3 is what the code currently does.
|
|
139
|
+
|
|
140
|
+
## 4. Conformance table
|
|
141
|
+
|
|
142
|
+
Audited against a full SNB15 run (2064 symbols, all mapped).
|
|
143
|
+
|
|
144
|
+
| Family | N | Representative | SM category | WM bound | Reachable colours |
|
|
145
|
+
| --- | ---: | --- | --- | :-: | --- |
|
|
146
|
+
| `CM_CELL` | 225 | `Bgate_HtoD_C1::GC_gate_G4` | Gating | yes | red, yellow, orange |
|
|
147
|
+
| `SG_H` | 165 | `SA_SG<t>_B4::WM1_Apop` | **WM** | yes | orange → yellow |
|
|
148
|
+
| `SG_D` | 165 | `SA_SG<t>_B4::WM1_Apop` | **WM** | yes | orange → yellow |
|
|
149
|
+
| `LMA_OUT_H` | 135 | `Gate_LMA_W_<wt>_B2a::GC_gate_G4` | Gating | yes | red, yellow, orange |
|
|
150
|
+
| `LMA_OUT_D` | 135 | `Gate_LMA_W_<wt>_B2a::GC_gate_G4` | Gating | yes | red, yellow, orange |
|
|
151
|
+
| `SGIN_H` | 165 | `Gate_SG_CM_SG<t>_B8::GC_gate_G4` | Gating | no | red only |
|
|
152
|
+
| `SGIN_D` | 165 | `Gate_SG_CM_SG<t>_B8::GC_gate_G4` | Gating | no | red only |
|
|
153
|
+
| `SG_OUT_H` | 165 | `Gate_SG_W_SG<t>_B12::GC_gate_G4` | Gating | no | red only |
|
|
154
|
+
| `SG_OUT_D` | 165 | `Gate_SG_W_SG<t>_B12::GC_gate_G4` | Gating | no | red only |
|
|
155
|
+
| `B2_LINK_H` | 165 | `L_Bgate_SG<t>_W_B2::GC_gate_G4` | Gating | yes | red, yellow, orange |
|
|
156
|
+
| `B2_LINK_D` | 165 | `L_Bgate_SG<t>_W_B2::GC_gate_G4` | Gating | yes | red, yellow, orange |
|
|
157
|
+
| `WORD` | 15 | `MA_Word_A1` | **Other** | no | red only |
|
|
158
|
+
| `H_RELAY` | 15 | `HD_Row_CM_in_B10` | **Other** | no | red only |
|
|
159
|
+
| `D_RELAY` | 15 | `HD_Row_CM_in_B10` | **Other** | no | red only |
|
|
160
|
+
| `CM_OUT_H` | 15 | `HD_Row_CM_out_B11` | **Other** | no | red only |
|
|
161
|
+
| `CM_OUT_D` | 15 | `HD_Row_CM_out_B11` | **Other** | no | red only |
|
|
162
|
+
| `WORD_INHIB` | 15 | `MA_Word_inhib_A1a` | **Other** | no | blue |
|
|
163
|
+
| `GLOBAL_INHIB` | 1 | none — synthesised `max` over `WORDINHIB_*` (`:1354-1361`) | — | no | blue |
|
|
164
|
+
| `INPUT` | 158 | external input rows | External | no | red only |
|
|
165
|
+
|
|
166
|
+
Symbols by SM category of their representative: **Gating 1485, WM 330,
|
|
167
|
+
Other 90, External 158, synthesised 1**.
|
|
168
|
+
|
|
169
|
+
### WM coverage
|
|
170
|
+
|
|
171
|
+
A WM must be attributed to the circuit that *owns* it, not to the
|
|
172
|
+
`circ_id` it happens to be filed under. Per SM A.4 a linked-binding
|
|
173
|
+
circuit is **two gating circuits sharing one WM population**; the row map
|
|
174
|
+
files that shared WM under the forward gate, so reading ownership off
|
|
175
|
+
`circ_id` double-counts and mislabels.
|
|
176
|
+
|
|
177
|
+
Verified in the architecture — `Bgate_SG1Verb_B1::WM1_Apop` (row 349)
|
|
178
|
+
outputs to `Bgate_SG1Verb_B1::GC_disinhibition_G2` (352) **and**
|
|
179
|
+
`L_Bgate_SG1Verb_W_B2::GC_disinhibition_G2` (416). Same pattern for
|
|
180
|
+
`Bgate_W_C_A2::WM1_Apop` (172) → (175) and (223).
|
|
181
|
+
|
|
182
|
+
Of the architecture's **1485 WM pairs**, symbols are bound to
|
|
183
|
+
**1020 (69%)**:
|
|
184
|
+
|
|
185
|
+
| WM owner | Pairs | Gates sharing it | Symbol |
|
|
186
|
+
| --- | ---: | --- | --- |
|
|
187
|
+
| CM binding cell | 225 | `Bgate_HtoD_C1` + `L_Bgate_DtoH_C2` | `CM_CELL` ✓ |
|
|
188
|
+
| LMA→SG linked-binding | 330 | `Bgate_SG<t>_B1` + `L_Bgate_SG<t>_W_B2` | `B2_LINK_H/D` ✓ (§6 B) |
|
|
189
|
+
| SG sub-assembly (SA) | 330 | standalone WM in the SG circuit | `SG_H`/`SG_D` ✓ |
|
|
190
|
+
| LMA (`MA_<wt>_A3`) | 135 | standalone WM population | `LMA_OUT_H/D` ✓ (§6 A) |
|
|
191
|
+
| SA-WM (`SA_WM_SG<t>_B9`) | 330 | standalone WM in the SG circuit | **none** (§6 C) |
|
|
192
|
+
| LMA↔W linked-binding | 135 | `Bgate_W_<wt>_A2` + `L_Bgate_LMA_W_<wt>_A2a` | **none** (§6 C) |
|
|
193
|
+
|
|
194
|
+
The video therefore shows 69% of the model's stored sentence structure —
|
|
195
|
+
the quantity the paper isolates as the WM category.
|
|
196
|
+
|
|
197
|
+
## 5. Design notes (not defects)
|
|
198
|
+
|
|
199
|
+
**SG symbols represent a WM population, by design.** SM D.1.5: "The core
|
|
200
|
+
population of an SG circuit is a WM population referred to as a
|
|
201
|
+
sub-assembly (SA)." So for all 330 `SG_H`/`SG_D` symbols
|
|
202
|
+
`primary_index == wm1_index` — the SA *is* both the representative and
|
|
203
|
+
the WM. Consequently `rep_only` is structurally zero and these symbols
|
|
204
|
+
never render pure red; they sit orange and drift yellow as `WM2_Bpop`
|
|
205
|
+
outruns `WM1_Apop`. That reflects the architecture rather than
|
|
206
|
+
contradicting it. It does mean the red/yellow contrast carries no
|
|
207
|
+
information on SG nodes: they are WM nodes throughout.
|
|
208
|
+
|
|
209
|
+
**`Gate_LMA_W_<wt>_B2a` is not the LMA.** Despite the `LMA_OUT_*` family
|
|
210
|
+
name it is the LMA-selective gating circuit on the CM→W *output* path
|
|
211
|
+
(`D-N-out` / `H-V-out` in SM figure S9), disinhibited by
|
|
212
|
+
`EX8H/D_LMA_out_<wt>_<arm>`. In a run with no retrieval phase it
|
|
213
|
+
correctly stays silent for the whole simulation.
|
|
214
|
+
|
|
215
|
+
## 6. Defects
|
|
216
|
+
|
|
217
|
+
### A — LMA symbols had no WM binding — **FIXED**
|
|
218
|
+
|
|
219
|
+
`_build_mappings` did attempt a WM pair for `LMA_OUT_H`/`LMA_OUT_D`, but
|
|
220
|
+
searched the wrong circuit:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
circ = f"Gate_LMA_W_{s.sg_type}_B2a"
|
|
224
|
+
wm1, wm2 = _find_wm_pair(rows, circ_id=circ, ..., mat_id="S_G") # was
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`Gate_LMA_W_<wt>_B2a` contains only the four `GC_*` gate populations — no
|
|
228
|
+
WM at all. The LMA lives in a different circuit, `MA_<wt>_A3`, which holds
|
|
229
|
+
exactly `WM1_Apop`/`WM2_Bpop`. The lookup silently returned `(-1, -1)`,
|
|
230
|
+
so `t_wm = 0` and yellow was arithmetically unreachable for all 270 LMA
|
|
231
|
+
symbols — defeating the defining property in SM D.1.1.
|
|
232
|
+
|
|
233
|
+
The lookup is now keyed on the LMA circuit and the word group:
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
wm1, wm2 = _find_wm_pair(rows, circ_id=f"MA_{s.sg_type}_A3",
|
|
237
|
+
mat_id=f"W_G{s.row}") # now
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
All 270 LMA symbols now resolve a WM pair, verified correct for every
|
|
241
|
+
word type and row. Because `Gate_LMA_W_<wt>_B2a` exists per arm (270)
|
|
242
|
+
while `MA_<wt>_A3` is per row (135), the H and D symbols of a row share
|
|
243
|
+
one latch and light together.
|
|
244
|
+
|
|
245
|
+
Worked example — "Sue eats pizza", the C LMA of row 1:
|
|
246
|
+
|
|
247
|
+
| Row | Circuit :: population | Peak | Before | After |
|
|
248
|
+
| --- | --- | ---: | --- | --- |
|
|
249
|
+
| 254 | `MA_C_A3::WM1_Apop` | 99.99 | unmapped | **bound as `wm1`** |
|
|
250
|
+
| 255 | `MA_C_A3::WM2_Bpop` | 100.00 | unmapped | **bound as `wm2`** |
|
|
251
|
+
| 714 | `Gate_LMA_W_C_B2a::GC_gate_G4` (H) | 0.005 | representative | representative |
|
|
252
|
+
| 1059 | `Gate_LMA_W_C_B2a::GC_gate_G4` (D) | 0.005 | representative | representative |
|
|
253
|
+
| 158 | `MA_Word_A1[W_G0]` | 98.17 @ 10 ms | red flash, gone by ~25 ms | unchanged |
|
|
254
|
+
|
|
255
|
+
The C LMA holds `WM2 = 100` from ~15 ms until inhibited at 140 ms by
|
|
256
|
+
`MA_C_inhib_A3a` (the `Clause_inhib` instruction). Colour of
|
|
257
|
+
`LMAOUT_H_r00_C` after the fix, computed with the renderer's own maths:
|
|
258
|
+
|
|
259
|
+
| t (ms) | rep | WM | `t_rep` | `t_wm` | Colour |
|
|
260
|
+
| ---: | ---: | ---: | ---: | ---: | --- |
|
|
261
|
+
| 0 | 0.00 | 0.00 | 0.000 | 0.000 | grey |
|
|
262
|
+
| 20 | 0.00 | 99.89 | 0.000 | 0.999 | **yellow** |
|
|
263
|
+
| 60 | 0.00 | 100.00 | 0.000 | 1.000 | **yellow** |
|
|
264
|
+
| 100 | 0.00 | 100.00 | 0.000 | 1.000 | **yellow** |
|
|
265
|
+
| 140 | 0.00 | 100.00 | 0.000 | 1.000 | **yellow** |
|
|
266
|
+
| 160 | 0.00 | 0.20 | 0.000 | 0.000 | grey |
|
|
267
|
+
| 200 | 0.00 | 0.00 | 0.000 | 0.000 | grey |
|
|
268
|
+
|
|
269
|
+
Yellow across exactly the latched stretch, extinguishing with the
|
|
270
|
+
commanded inhibition — the SM D.1.1 signature.
|
|
271
|
+
|
|
272
|
+
### B — `B2_LINK` symbols had no WM binding — **FIXED**
|
|
273
|
+
|
|
274
|
+
The same class of error as A. `B2_LINK_H`/`B2_LINK_D` draw the reverse
|
|
275
|
+
gate of the LMA→SG linked-binding circuit, and the WM lookup searched
|
|
276
|
+
that gate's own `circ_id`:
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
circ = f"L_Bgate_{s.sg_type}_W_B2"
|
|
280
|
+
wm1, wm2 = _find_wm_pair(rows, circ_id=circ, ..., mat_id="S_G") # was
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
The shared WM is filed under the *forward* gate. The row/`mat_id` keys
|
|
284
|
+
were already correct; only the circuit was wrong:
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
wm1, wm2 = _find_wm_pair(rows, circ_id=f"Bgate_{s.sg_type}_B1",
|
|
288
|
+
h_row=..., d_row=..., mat_id="S_G") # now
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
All 330 `B2_LINK` symbols now resolve a WM pair, verified correct for
|
|
292
|
+
every SG type and row. Combined with A, WM coverage rises 555 → 1020 of
|
|
293
|
+
1485 pairs (37% → 69%).
|
|
294
|
+
|
|
295
|
+
### C — Two WM owners have no symbol at all
|
|
296
|
+
|
|
297
|
+
- **LMA↔W linked-binding** (135 pairs). *Neither* of its gates —
|
|
298
|
+
`Bgate_W_<wt>_A2` or `L_Bgate_LMA_W_<wt>_A2a` — is on the schematic,
|
|
299
|
+
even though Figure 1B draws this binding prominently as the black
|
|
300
|
+
diamond between the word population and the LMA. In the §6 A worked
|
|
301
|
+
example it latched at `WM1≈50`, `WM2≈100` and held past the end of the
|
|
302
|
+
run, entirely unseen.
|
|
303
|
+
- **SA-WM** (`SA_WM_SG<t>_B9`, 330 pairs). A standalone WM inside the SG
|
|
304
|
+
circuit (SM D.1.5, figure S8), with no symbol of its own.
|
|
305
|
+
|
|
306
|
+
Unlike A and B these cannot be fixed in the mapper: there is no symbol to
|
|
307
|
+
attach a WM to. Closing them requires **new symbols in the schematic
|
|
308
|
+
template** (`rnba/schematic_visualization.py`, and correspondingly the
|
|
309
|
+
reference PDFs under `docs/templates/`), which changes the canonical
|
|
310
|
+
static schematic as well as the video. That is a modelling/design
|
|
311
|
+
decision, not a bug fix.
|
|
312
|
+
|
|
313
|
+
### D — The Other category is split arbitrarily between red and blue
|
|
314
|
+
|
|
315
|
+
SM I.1 makes Other a first-class category, plotted separately in figure
|
|
316
|
+
4B. In the renderer its 90 symbols are split: 15 (`WORD_INHIB`) render
|
|
317
|
+
blue, the other 75 (`WORD`, `H_RELAY`, `D_RELAY`, `CM_OUT_H`, `CM_OUT_D`)
|
|
318
|
+
render red and are indistinguishable from Gating symbols. Neither the
|
|
319
|
+
blue branch nor the red default corresponds to a category boundary in the
|
|
320
|
+
model.
|
|
321
|
+
|
|
322
|
+
### E — Cosmetic
|
|
323
|
+
|
|
324
|
+
`raw_rep` at `:1409` is computed and discarded; `t_rep` comes from the
|
|
325
|
+
precomputed `src_activity` map at `:1412`. Same value, redundant work.
|
|
326
|
+
|
|
327
|
+
## 7. Reproducing the audit
|
|
328
|
+
|
|
329
|
+
Render any run with `--out-dir DIR`; the mapper writes
|
|
330
|
+
`DIR/representative_mapping.csv` (`symbol_id, family, mode,
|
|
331
|
+
primary_index, secondary_index, aux_index, wm1_index, wm2_index,
|
|
332
|
+
source`). Join its index columns against the simulator's
|
|
333
|
+
`--output-row-map` CSV to recover `circ_id`/`pop_id` per symbol, and
|
|
334
|
+
classify with the `pop_id` rule in §2.
|
|
335
|
+
|
|
336
|
+
- `wm1_index == -1` → the symbol can never render yellow.
|
|
337
|
+
- `primary_index == wm1_index` → the symbol can never render red.
|
|
338
|
+
|
|
339
|
+
## See also
|
|
340
|
+
|
|
341
|
+
- `docs/simulation-and-visualization-workflow.tex` — the simulate-to-video workflow
|
|
342
|
+
- `docs/snb15_population_categories.md` — the 30-category population classification
|
|
343
|
+
- `docs/instruction-file-formats.md` — instruction times are timestep indices, `h = 0.1` ms
|
|
344
|
+
- `rnba/schematic_visualization.py` — the base schematic the overlay is drawn on
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
\documentclass[11pt]{article}
|
|
2
|
+
|
|
3
|
+
\usepackage[margin=1in]{geometry}
|
|
4
|
+
\usepackage{hyperref}
|
|
5
|
+
\usepackage{enumitem}
|
|
6
|
+
\usepackage{listings}
|
|
7
|
+
\usepackage{xcolor}
|
|
8
|
+
|
|
9
|
+
\lstset{
|
|
10
|
+
basicstyle=\ttfamily\small,
|
|
11
|
+
breaklines=true,
|
|
12
|
+
frame=single,
|
|
13
|
+
columns=fullflexible,
|
|
14
|
+
keepspaces=true,
|
|
15
|
+
showstringspaces=false,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
\newcommand{\opt}[1]{\texttt{#1}}
|
|
19
|
+
|
|
20
|
+
\title{RNBA: From Architecture to Activity Video}
|
|
21
|
+
\author{RNBA documentation}
|
|
22
|
+
\date{}
|
|
23
|
+
|
|
24
|
+
\begin{document}
|
|
25
|
+
\maketitle
|
|
26
|
+
|
|
27
|
+
\noindent
|
|
28
|
+
This note describes the two-step workflow that turns an RNBA blackboard
|
|
29
|
+
architecture and an instruction file into a rendered activity-flow video.
|
|
30
|
+
It corresponds to the commands in \texttt{\textasciitilde/NBAExperiments/start}
|
|
31
|
+
and explains every option used there. The example presents the sentence
|
|
32
|
+
\emph{``Sue eats pizza''} to the SNB15 network and renders the resulting
|
|
33
|
+
dynamics.
|
|
34
|
+
|
|
35
|
+
\section*{Overview}
|
|
36
|
+
|
|
37
|
+
The workflow has two stages, each a separate command:
|
|
38
|
+
|
|
39
|
+
\begin{enumerate}[leftmargin=*]
|
|
40
|
+
\item \textbf{Simulate} with \texttt{rnba-run} (the Python simulator).
|
|
41
|
+
It reads the architecture and instruction files, integrates the
|
|
42
|
+
network dynamics, and writes the population traces to CSV.
|
|
43
|
+
\item \textbf{Visualise} with \texttt{python -m rnba.visualize\_activity\_flow}.
|
|
44
|
+
It overlays those traces on the canonical SNB15 schematic and
|
|
45
|
+
renders an MP4 video.
|
|
46
|
+
\end{enumerate}
|
|
47
|
+
|
|
48
|
+
The stages communicate through the CSV files written in step~1 and read
|
|
49
|
+
back in step~2. All times inside RNBA are integer timestep indices with
|
|
50
|
+
a fixed step $h = 0.1$~ms.
|
|
51
|
+
|
|
52
|
+
\section*{Environment setup}
|
|
53
|
+
|
|
54
|
+
\begin{lstlisting}
|
|
55
|
+
python3 -m venv .venv
|
|
56
|
+
source .venv/bin/activate
|
|
57
|
+
\end{lstlisting}
|
|
58
|
+
|
|
59
|
+
\noindent
|
|
60
|
+
Creates and activates a virtual environment. Install the package into it
|
|
61
|
+
with \texttt{pip install rnba} (version 0.2.2 or later is required for the
|
|
62
|
+
\opt{--workers} option in step~2).
|
|
63
|
+
|
|
64
|
+
\section*{Step 1: Run the simulation}
|
|
65
|
+
|
|
66
|
+
\begin{lstlisting}
|
|
67
|
+
rnba-run \
|
|
68
|
+
--architecture ~/NBAExperiments/Sue_Eats_Pizza/RNBA_arch_SGall_SNB15.txt \
|
|
69
|
+
--instruction ~/NBAExperiments/Sue_Eats_Pizza/instruction.txt \
|
|
70
|
+
--output ~/NBAExperiments/Sue_Eats_Pizza/RNBA_simulation_output.csv \
|
|
71
|
+
--output-row-map ~/NBAExperiments/Sue_Eats_Pizza/RNBA_row_map.csv \
|
|
72
|
+
--output-named \
|
|
73
|
+
--output-inputs ~/NBAExperiments/Sue_Eats_Pizza/inputs.csv
|
|
74
|
+
\end{lstlisting}
|
|
75
|
+
|
|
76
|
+
\begin{description}[leftmargin=0pt,style=nextline]
|
|
77
|
+
\item[\opt{--architecture} FILE]
|
|
78
|
+
The blackboard architecture (here the SNB15 configuration). It
|
|
79
|
+
describes every population and its wiring; \texttt{rnba-run} builds
|
|
80
|
+
the network from it. Required.
|
|
81
|
+
|
|
82
|
+
\item[\opt{--instruction} FILE]
|
|
83
|
+
The instruction file giving the timings at which external inputs
|
|
84
|
+
(word, gating, and binding populations) switch on and off. It uses
|
|
85
|
+
the unified instruction format and is parsed strictly. The
|
|
86
|
+
simulation duration is derived automatically from the schedule (plus
|
|
87
|
+
a settling tail; see \opt{--tail-steps}).
|
|
88
|
+
|
|
89
|
+
\item[\opt{--output} FILE]
|
|
90
|
+
Destination CSV for the population traces: one row per timestep, one
|
|
91
|
+
column per population, with a \texttt{time\_ms} first column.
|
|
92
|
+
|
|
93
|
+
\item[\opt{--output-row-map} FILE]
|
|
94
|
+
Writes the mapping between CSV column (row index) and population
|
|
95
|
+
metadata (\texttt{pop\_id}, type, circuit, etc.). The visualiser and
|
|
96
|
+
other downstream tools use it to know which column is which
|
|
97
|
+
population.
|
|
98
|
+
|
|
99
|
+
\item[\opt{--output-named}]
|
|
100
|
+
Also writes a second copy of the trace CSV whose column headers are
|
|
101
|
+
the human-readable \texttt{pop\_id[row]} names rather than bare row
|
|
102
|
+
indices. With no argument it defaults to \texttt{<output>\_named.csv}.
|
|
103
|
+
Because \opt{--output-inputs} is also given, a named copy of the
|
|
104
|
+
input traces is written alongside it as well.
|
|
105
|
+
|
|
106
|
+
\item[\opt{--output-inputs} FILE]
|
|
107
|
+
Writes the external input traces (the driven activation of the input
|
|
108
|
+
populations) to a separate CSV. Step~2 reads this to display the
|
|
109
|
+
inputs in the video.
|
|
110
|
+
\end{description}
|
|
111
|
+
|
|
112
|
+
\paragraph{Duration.}
|
|
113
|
+
No duration flag is passed, so the length is computed from the
|
|
114
|
+
instruction schedule plus \opt{--tail-steps} (default 500 settling
|
|
115
|
+
steps). Override with \opt{--t-end} MS or \opt{--n-steps} N if a fixed
|
|
116
|
+
length is needed.
|
|
117
|
+
|
|
118
|
+
\section*{Step 2: Render the activity-flow video}
|
|
119
|
+
|
|
120
|
+
\begin{lstlisting}
|
|
121
|
+
python -m rnba.visualize_activity_flow \
|
|
122
|
+
--dpi 75 --workers 6 \
|
|
123
|
+
--architecture RNBA_arch_SGall_SNB15.txt \
|
|
124
|
+
--trace-csv RNBA_simulation_output.csv \
|
|
125
|
+
--inputs-csv inputs.csv \
|
|
126
|
+
--out-dir activity_flow_out \
|
|
127
|
+
--render-video \
|
|
128
|
+
--frames-dir activity_flow_out/frames \
|
|
129
|
+
--video-out Sue_Eats_Pizza_activity.mp4 \
|
|
130
|
+
--fps 25 --step-ms 1.0
|
|
131
|
+
\end{lstlisting}
|
|
132
|
+
|
|
133
|
+
\noindent
|
|
134
|
+
This command is run from inside the \texttt{Sue\_Eats\_Pizza} directory,
|
|
135
|
+
so the file arguments are relative paths referring to the outputs of
|
|
136
|
+
step~1.
|
|
137
|
+
|
|
138
|
+
\begin{description}[leftmargin=0pt,style=nextline]
|
|
139
|
+
\item[\opt{--dpi} 75]
|
|
140
|
+
Rendering resolution. The figure canvas is $13\times18$ inches, so
|
|
141
|
+
\opt{--dpi}~75 yields $975\times1350$-pixel frames. Lower DPI gives
|
|
142
|
+
smaller files but only marginally faster rendering, because the cost
|
|
143
|
+
is dominated by drawing the schematic rather than rasterising pixels.
|
|
144
|
+
|
|
145
|
+
\item[\opt{--workers} 6]
|
|
146
|
+
Number of parallel worker processes for frame rendering. Each worker
|
|
147
|
+
builds its own copy of the base schematic and renders a share of the
|
|
148
|
+
frames; the output is identical to a sequential run. Choose a value
|
|
149
|
+
up to the CPU core count (each worker holds a full figure, so watch
|
|
150
|
+
memory). Requires rnba 0.2.2 or later.
|
|
151
|
+
|
|
152
|
+
\item[\opt{--architecture} FILE]
|
|
153
|
+
The same architecture file as step~1. The visualiser uses it to lay
|
|
154
|
+
out the schematic and to map trace columns onto schematic symbols.
|
|
155
|
+
|
|
156
|
+
\item[\opt{--trace-csv} FILE]
|
|
157
|
+
The population-trace CSV produced by step~1 (\opt{--output}). Its
|
|
158
|
+
values drive the brightness and edge intensity of the overlay.
|
|
159
|
+
|
|
160
|
+
\item[\opt{--inputs-csv} FILE]
|
|
161
|
+
The external-input trace CSV produced by step~1
|
|
162
|
+
(\opt{--output-inputs}). Merged into each frame so the driving
|
|
163
|
+
inputs are shown alongside the network activity.
|
|
164
|
+
|
|
165
|
+
\item[\opt{--out-dir} DIR]
|
|
166
|
+
Output directory for the renderer's auxiliary artifacts (symbol
|
|
167
|
+
catalogue, representative mapping, and the single-frame preview PNG).
|
|
168
|
+
|
|
169
|
+
\item[\opt{--render-video}]
|
|
170
|
+
Enables the full video pass. Without it the tool writes only a
|
|
171
|
+
single static preview frame. With it, frames are sampled across the
|
|
172
|
+
whole trace and assembled into an MP4 with \texttt{ffmpeg} (which
|
|
173
|
+
must be on \texttt{PATH}).
|
|
174
|
+
|
|
175
|
+
\item[\opt{--frames-dir} DIR]
|
|
176
|
+
Directory for the individual PNG frames. Any existing
|
|
177
|
+
\texttt{frame\_*.png} files there are cleared first, then one PNG is
|
|
178
|
+
written per sampled timestep before muxing.
|
|
179
|
+
|
|
180
|
+
\item[\opt{--video-out} FILE]
|
|
181
|
+
Path of the final MP4. Encoded with \texttt{libx264} / \texttt{yuv444p}
|
|
182
|
+
for broad player compatibility.
|
|
183
|
+
|
|
184
|
+
\item[\opt{--fps} 25]
|
|
185
|
+
Frames per second of the output video (playback rate).
|
|
186
|
+
|
|
187
|
+
\item[\opt{--step-ms} 1.0]
|
|
188
|
+
Sampling stride over the trace, in milliseconds: one frame is
|
|
189
|
+
rendered per 1~ms of simulated time. Smaller values give smoother,
|
|
190
|
+
longer videos with more frames; larger values render faster.
|
|
191
|
+
\end{description}
|
|
192
|
+
|
|
193
|
+
\paragraph{Result.}
|
|
194
|
+
\texttt{Sue\_Eats\_Pizza\_activity.mp4} shows the activity flowing
|
|
195
|
+
through the blackboard as the sentence is presented, with the auxiliary
|
|
196
|
+
CSVs and preview PNG left in \texttt{activity\_flow\_out/} for
|
|
197
|
+
inspection.
|
|
198
|
+
|
|
199
|
+
\section*{Related documentation}
|
|
200
|
+
|
|
201
|
+
\begin{itemize}[leftmargin=*]
|
|
202
|
+
\item Instruction file format: \texttt{docs/instruction-file-formats.md}
|
|
203
|
+
\item Bindings file format: \texttt{docs/bindings-file-format.md}
|
|
204
|
+
\item Full option lists: \texttt{rnba-run -{}-help} and
|
|
205
|
+
\texttt{python -m rnba.visualize\_activity\_flow -{}-help}
|
|
206
|
+
\end{itemize}
|
|
207
|
+
|
|
208
|
+
\end{document}
|