Skip to content

feat(dashboard): SBD visual place-learning family (sbd-place) + analysis pages - #249

Merged
mbreiser merged 4 commits into
mainfrom
feat/dashboard-sbd-place-learning
Nov 11, 2026
Merged

mbreiser merged 4 commits into
mainfrom
feat/dashboard-sbd-place-learning

Conversation

@shubhamTR

@shubhamTR shubhamTR commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Runs of the rig03 SBD visual place-learning protocols (p3-sbd-placelearning-*, sbd-bias-*; G6 ports of the G4.1 p058 / p066 / p067 protocols) showed up in the dashboard as "generic protocol" — and because the filenames start with p3-, the bare p3 substring would have routed them into the Heisenberg legacy branch. This PR adds the sbd-place family and its analysis pages, and an optomotor family for the optomotor ± opto LED tests.

  • analysis-core.js — protocolInfo recognises the family before the p3 checks (filename contains sbd, or conditions = preprobe + train_plus/train_minus / pair_m<k>_p<k>) → {family:'sbd-place', sbdVariant: base|coupled|uncoupled|bias, sbdVersion: v1|v2|v3}. New exported helpers: sbdZone (safe zone from the first training bout's logged led_activation zone; default heat [8,158) → 50 safe frames centred on 183), sbdBouts (one row per Mode-3 interval, not per step — the uncoupled control runs two bouts per pair_m<k>_p<k> step; start frame/side, pattern id → picture rotation k, safe / opposite / LED-on fractions, first-entry latency, PI), sbdStageSummary, sbdOccupancy. Scoring is in frame space, so the uncoupled control's fixed heat map is scored exactly like the coupled protocol.
  • analysis-core.js, optomotor family — the optomotor ± opto LED tests (optomotor_led_test, optomotor_test_60deg, optomotor_test_60deg_tf; conditions grating_cw_noled / grating_cw_led) are classified before the p0 rule, which claimed them through grating_cw_*. The filename must start with optomotor_, so protocols with "optomotor" in the name and no opto LED (g6_color_optomotor_test, simple_optomotor_protocol) stay generic. The label names the grating period; the pages are the generic set.
  • plot-specs.js — five pages: time in the safe zone per bout (chance line), time to first zone entry, LED-on fraction per bout, heading occupancy around the zone (zone + 15° ramps shaded, 5-bin circular boxcar), stage preference index (t safe − t opposite)/(t safe + t opposite) with "opposite" = the zone rotated 180°. Group mode draws per-fly lines + mean ± SEM; every page exports CSV rows. buildPages dispatches sbd-place before the generic fallback.
  • README — "SBD visual place learning" section.
  • tests/test-dashboard-sbd.js (new, auto-discovered by pixi run test) — synthetic behavior_v2 log with an uncoupled pair step: classification (incl. the p3- trap, Heisenberg files staying p3, optomotor vs p0, and "optomotor" inside a filename staying generic), zone geometry, bout rows, fractions, PI, stage summary, occupancy, buildPages.

Not in this PR: the v3 sham and mid-probe stages are labeled but not scored (follow-up).

Context: SBD protocols + patterns 46–49 live in reiserlab/cshl-2026-course (protocols/rig03-sr/); the start_frame runner/bridge work shipped in #223.

Tier

next candidate

Release notes

Dashboard

  • SBD visual place-learning runs now get their own analysis pages instead of the generic protocol view: time in the safe zone per bout, time to the first zone entry, LED-on fraction, heading occupancy around the zone, and a preprobe / training / probe preference index, with per-fly lines and mean ± SEM in group mode and CSV export on every page.
  • The run catalog and the group filter list these runs as sbd-place, so all variants and LED levels form one group. A loaded run shows the full label with the variant and protocol revision, for example "SBD place learning (coupled v3)".
  • Optomotor ± opto LED test runs are now their own family, optomotor, instead of being read as p0 optogenetic-intensity runs. A loaded run shows the grating period in its label; the pages are the generic set.

Test plan

  • pixi run node tests/test-dashboard-sbd.js — 17/17
  • pixi run test on a trial merge with main (2026-11-11) — 74/74 files
  • Parsed all 20 SBD run logs in cshl-2026-course/runlogs/rig03-sr through the new family in Node: every file → sbd-place with the right variant, heat [8,158) read from the log, 22 bouts (preprobe + 20 training + probe), alternating +/− start sides, 0 parse errors; group pages build (21 traces each)
  • Review (2026-11-10): all 203 run logs in arena-experiments (66b42ce) classified with main and with this branch — 139 labels change, all intended (SBD and optomotor runs); no real p0 or Heisenberg p3 run changes; 0 parse errors
  • The 30 real optomotor run logs keep the same catalog and loaded-run labels after the narrower filename rule (3ceb29f)
  • Browser check on /next/ once the candidate is published (the Node test exercises the page objects; the UI consumes title/description/figure/csvRows generically)
  • No footer / version / release-notes-file edits (release tiers)

🤖 Generated with Claude Code

shubhamTR and others added 4 commits October 12, 2026 11:01
…sis pages

Runs of the rig03 SBD protocols (p3-sbd-placelearning-*, sbd-bias-*) landed in
the dashboard as "generic protocol" — worse, a filename starting with p3- would
have fallen into the Heisenberg legacy branch via the bare "p3" substring.
Now:

- analysis-core: `protocolInfo` recognises the family BEFORE the p3 checks
  (filename contains "sbd", or conditions = preprobe + train_plus/train_minus /
  pair_m<k>_p<k>) → `{family:'sbd-place', sbdVariant: base|coupled|uncoupled|bias}`.
  New exported helpers: `sbdZone` (safe zone from the first training bout's
  logged led_activation zone, default heat [8,158) → 50 safe frames centred on
  183), `sbdBouts` (ONE ROW PER MODE-3 INTERVAL, not per step — the uncoupled
  control runs two bouts per pair step; start frame/side, pattern id → rotation
  k, safe / opposite / LED-on fractions, first-entry latency, PI),
  `sbdStageSummary` (time-weighted preprobe / training / probe), `sbdOccupancy`
  (histogram in degrees from the zone centre). Scoring is in frame space, so the
  uncoupled control's fixed heat map is scored like the coupled protocol.
- plot-specs: five SBD pages — time in the safe zone per bout (chance line),
  time to the first zone entry, LED-on fraction per bout, heading occupancy
  around the zone (zone + 15° ramps shaded, 5-bin circular boxcar), stage
  preference index (t safe − t opposite)/(t safe + t opposite) with "opposite" =
  the zone rotated 180°. Group mode: per-fly lines + mean ± SEM; CSV rows on
  every page. `buildPages` dispatches `sbd-place` before the generic fallback.
- README: "SBD visual place learning" section.
- tests/test-dashboard-sbd.js (new, auto-discovered): synthetic behavior_v2 log
  with an uncoupled pair step; classification incl. the p3-prefix trap and the
  Heisenberg files staying p3, zone geometry, bout rows, fractions, PI, stage
  summary, occupancy, buildPages.

Checked against all 20 SBD run logs in reiserlab/cshl-2026-course
(runlogs/rig03-sr): every file → sbd-place with the right variant, heat [8,158)
read from the log, 22 bouts (preprobe + 20 training + probe), alternating +/−
start sides, 0 parse errors; group pages build (21 traces each).
`pixi run test`: the new file passes; the 5 failing files
(arena-studio-alt, project-skills, protocol-roundtrip-v3, studio-runtime-vars,
studio-shell) fail identically on main. No footer/version bump (release tiers).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…og label

protocolInfo() gains an `optomotor` family, checked before the p0 rule: the rig03
optomotor ± opto LED tests (optomotor_led_test, optomotor_test_60deg, _tf) name their
gratings grating_cw_noled / grating_cw_led, which the p0 regex (grating_cw_<level>)
claimed, so they showed as "p0 optogenetic intensity". The label carries the grating
period (36° / 60°) and the temporal-frequency variant; pages are the generic set.

SBD labels now carry the protocol revision read from the filename (-v2-, -v3-; a
renamed v3 copy is recognised from its sham_preprobe / probe_mid / sham_probe
conditions): "SBD place learning (coupled v3)", "(bias v2)", "(uncoupled v2)";
`sbdVersion` is exposed for later use. The v3 sham / mid-probe stages are not scored
yet (follow-up).

tests/test-dashboard-sbd.js: two new checks (16/16).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The filename rule matched "optomotor" anywhere in the protocol name, so
protocols without an opto LED (g6_color_optomotor_smoke,
g6_color_optomotor_test, simple_optomotor_protocol) were labeled
"optomotor ± opto LED". The rule now needs the file name to start with
optomotor_. The condition-name rule (grating_cw_noled / grating_cw_led)
is unchanged.

Checked on the 30 real optomotor run logs in arena-experiments
(66b42ce): catalog and loaded-run labels are the same as before.

Co-Authored-By: Claude <noreply@anthropic.com>
…s the label

The README said the SBD variant and revision show in the catalog label.
The catalog and the group filter show the family id (sbd-place); the full
label shows on a loaded run.

Co-Authored-By: Claude <noreply@anthropic.com>
@mbreiser

Copy link
Copy Markdown
Contributor

@shubhamTR this is reviewed and good for the next candidate. To save you a round, two small commits are now on your branch and the description is updated. Pull before you push again.

What changed

  • 3ceb29f: the optomotor filename rule is narrower. The file name must start with optomotor_. Before, any name with "optomotor" in it matched, so g6_color_optomotor_smoke, g6_color_optomotor_test and simple_optomotor_protocol (no opto LED) would be labeled "optomotor ± opto LED". The condition-name rule is unchanged. Your 30 real optomotor run logs keep the same labels.
  • d973b42: README correction. The run catalog and the group filter show the family id (sbd-place, optomotor). The full label ("SBD place learning (coupled v3)") shows on a loaded run.
  • PR description: the same catalog correction in the release notes, the optomotor family added to the summary and release notes, and the test plan updated (17/17; 74/74 files on a trial merge with main).

Review result

All 203 run logs in arena-experiments (66b42ce) were classified with main and with this branch. 139 labels change, all intended. No real p0 or Heisenberg p3 run changes.

Still open, as a follow-up

Scoring of the v3 sham and mid-probe stages. Not needed for this PR.

🤖 Generated with Claude Code

@mbreiser
mbreiser merged commit ce0374f into main Nov 11, 2026
5 checks passed
@mbreiser
mbreiser deleted the feat/dashboard-sbd-place-learning branch November 11, 2026 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants