Commit 2ac5cc7
authored
LFP: electrode_offsets refactor for multi-report support (#3779)
Refactor the LFP electrode metadata representation from a scalar `num_electrodes` to a CSR-style `electrode_offsets` vector, enabling per-report electrode file support for multiple LFP reports with different electrode configurations.
Fix: #3784
## Motivation
The SONATA spec is moving `electrodes_file` from the global `run` section to individual LFP report blocks ([sonata-extension#34](BlueBrain/sonata-extension#34), [libsonata katta/per-report-electrodes-file](https://github.com/BlueBrain/libsonata/tree/katta/per-report-electrodes-file)). This enables different LFP reports to use different electrode weight files (e.g. deep probes vs surface EEG).
CoreNEURON currently stores a single set of electrode factors per cell with a scalar `num_electrodes`. To support multiple electrode files, we replace this with a CSR-style offsets array and add per-report slicing at report setup time.
## What this PR does
1. Replace `SecMapping::num_electrodes` (int) with `SecMapping::electrode_offsets` (vector<int>)
2. Update `nrnbbcore_register_mapping` to accept a Vector (offsets) instead of scalar int
3. Update the transfer callback to pass `vector<int>` instead of `int`
4. CoreNEURON `CellMapping` stores offsets, `num_electrodes()` derives from `offsets.back()`
5. File format: header line extended with offset count + values
6. `get_lfp_vars_to_report` uses report-specific offset/count slicing for its output buffer
7. neurodamus: passes `Nd.Vector([0, N])` instead of scalar `N` (or `[0, N, N+M]` for multi-report)
## What does NOT change
- `lfp_calc()` computation — iterates all electrodes as before (factors are concatenated)
- LFP output — bit-for-bit identical for single-report case
- Performance — no hot-path allocations added; offsets resolved at setup time only
## Design
For a single report with N electrodes: `electrode_offsets = [0, N]`
For two reports with 2 and 3 electrodes: `electrode_offsets = [0, 2, 5]`
Each LFP report (by order in report.conf) knows its slice: report i uses electrodes `[offsets[i], offsets[i+1])`. The factor vector per segment is the concatenation of all reports' factors.
`lfp_calc()` always computes over the full electrode set (all factors). The slicing only matters at report output time in `get_lfp_vars_to_report`.
## Related PRs (separate repos)
- **neurodamus:** Will adapt to read `electrodes_file` from per-report blocks (new libsonata API), load multiple electrode files, and pass concatenated offsets.
- **libsonata:** [katta/per-report-electrodes-file](https://github.com/BlueBrain/libsonata/tree/katta/per-report-electrodes-file)
- **sonata-extension:** [katta/strict-lfp-variable-name](https://github.com/BlueBrain/sonata-extension/tree/katta/strict-lfp-variable-name)
## Testing
- All existing ctest LFP tests pass unchanged (behavioral equivalence for single-report)
- All neurodamus `test_lfp.py` tests pass unchanged
- Multi-report correctness validated against sequential single-report runs1 parent d272e12 commit 2ac5cc7
16 files changed
Lines changed: 137 additions & 47 deletions
File tree
- src
- coreneuron
- apps
- io
- reports
- nrniv
- nrncore_write
- callbacks
- io
- utils
- test
- coreneuron/unit/lfp
- pytest_coreneuron
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
561 | 561 | | |
562 | 562 | | |
563 | 563 | | |
| 564 | + | |
564 | 565 | | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
565 | 569 | | |
566 | 570 | | |
567 | 571 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
109 | | - | |
| 109 | + | |
110 | 110 | | |
111 | 111 | | |
112 | 112 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
118 | 119 | | |
119 | 120 | | |
120 | 121 | | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
131 | 141 | | |
132 | | - | |
| 142 | + | |
133 | 143 | | |
134 | 144 | | |
135 | 145 | | |
| |||
148 | 158 | | |
149 | 159 | | |
150 | 160 | | |
151 | | - | |
| 161 | + | |
152 | 162 | | |
153 | 163 | | |
154 | 164 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
83 | 87 | | |
84 | 88 | | |
85 | 89 | | |
| |||
103 | 107 | | |
104 | 108 | | |
105 | 109 | | |
106 | | - | |
| 110 | + | |
107 | 111 | | |
108 | | - | |
| 112 | + | |
109 | 113 | | |
110 | 114 | | |
111 | 115 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | | - | |
64 | 63 | | |
65 | 64 | | |
66 | 65 | | |
| |||
71 | 70 | | |
72 | 71 | | |
73 | 72 | | |
74 | | - | |
| 73 | + | |
75 | 74 | | |
76 | 75 | | |
77 | 76 | | |
| 77 | + | |
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
258 | 258 | | |
259 | 259 | | |
260 | 260 | | |
| 261 | + | |
261 | 262 | | |
262 | 263 | | |
263 | 264 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
119 | | - | |
120 | | - | |
| 119 | + | |
| 120 | + | |
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
26 | | - | |
| 25 | + | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
584 | 584 | | |
585 | 585 | | |
586 | 586 | | |
587 | | - | |
| 587 | + | |
588 | 588 | | |
589 | 589 | | |
590 | 590 | | |
| |||
598 | 598 | | |
599 | 599 | | |
600 | 600 | | |
601 | | - | |
| 601 | + | |
| 602 | + | |
602 | 603 | | |
603 | 604 | | |
604 | 605 | | |
| |||
617 | 618 | | |
618 | 619 | | |
619 | 620 | | |
620 | | - | |
621 | | - | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
622 | 630 | | |
623 | 631 | | |
624 | 632 | | |
| |||
681 | 689 | | |
682 | 690 | | |
683 | 691 | | |
684 | | - | |
685 | | - | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
686 | 697 | | |
687 | 698 | | |
688 | 699 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
249 | 249 | | |
250 | 250 | | |
251 | 251 | | |
252 | | - | |
| 252 | + | |
253 | 253 | | |
254 | 254 | | |
255 | 255 | | |
| |||
259 | 259 | | |
260 | 260 | | |
261 | 261 | | |
262 | | - | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
263 | 265 | | |
264 | 266 | | |
265 | 267 | | |
| |||
0 commit comments