Skip to content

Commit 1de2948

Browse files
mbreiserclaude
andcommitted
feat: Experiment Designer v0.6 — YAML v2 protocol, plugins, 3 editor views
Migrate experiment designer from v1 to v2 YAML protocol with full plugin support (LEDControllerPlugin, BiasPlugin) and three synchronized editor views. Shared modules: - js/protocol-yaml.js: YAML parser (inline comment stripping), v1/v2 generators - js/plugin-registry.js: 13 command definitions across 2 plugins + controller Data model: conditions/phases now use commands[] arrays, enabling multi-command sequences with interleaved controller, plugin, and wait commands. Editor views: - Visual: command card builder with color-coded cards + Add Command dropdown - Table: collapsible spreadsheet with type badges and plugin param display - Timeline: SVG multi-lane visualization (controller spans, plugin markers, waits) Roundtrip validation: 130/130 JS tests (9 suites), 35/35 MATLAB tests. CI workflow updated for v2 paths and file checks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 28b1944 commit 1de2948

12 files changed

Lines changed: 4410 additions & 1045 deletions

.github/workflows/validate-protocol-roundtrip.yml

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ on:
44
push:
55
paths:
66
- 'experiment_designer.html'
7+
- 'js/protocol-yaml.js'
8+
- 'js/plugin-registry.js'
79
- 'tests/test-protocol-roundtrip.js'
810
- 'tests/generate-roundtrip-protocol.js'
11+
- 'tests/fixtures/v2_*.yaml'
912
- '.github/workflows/validate-protocol-roundtrip.yml'
1013
pull_request:
1114
paths:
1215
- 'experiment_designer.html'
16+
- 'js/protocol-yaml.js'
17+
- 'js/plugin-registry.js'
1318
- 'tests/test-protocol-roundtrip.js'
1419
- 'tests/generate-roundtrip-protocol.js'
1520
workflow_dispatch:
@@ -35,27 +40,33 @@ jobs:
3540

3641
- name: Verify generated files exist
3742
run: |
38-
echo "Checking generated YAML files..."
43+
echo "Checking generated files..."
3944
ls -la /tmp/roundtrip-output/
4045
test -f /tmp/roundtrip-output/test_protocol_v1.yaml || { echo "FAIL: test_protocol_v1.yaml not generated"; exit 1; }
41-
test -f /tmp/roundtrip-output/test_protocol_manifest.json || { echo "FAIL: manifest not generated"; exit 1; }
46+
test -f /tmp/roundtrip-output/test_protocol_manifest.json || { echo "FAIL: v1 manifest not generated"; exit 1; }
47+
test -f /tmp/roundtrip-output/test_protocol_v2.yaml || { echo "FAIL: test_protocol_v2.yaml not generated"; exit 1; }
48+
test -f /tmp/roundtrip-output/test_protocol_v2_manifest.json || { echo "FAIL: v2 manifest not generated"; exit 1; }
4249
echo "All generated files present."
4350
4451
- name: Summary
4552
if: always()
4653
run: |
4754
echo "## Protocol YAML Roundtrip Validation" >> $GITHUB_STEP_SUMMARY
4855
echo "" >> $GITHUB_STEP_SUMMARY
49-
echo "### Test Suites:" >> $GITHUB_STEP_SUMMARY
50-
echo "- V1 Generate → Parse Roundtrip (33 checks)" >> $GITHUB_STEP_SUMMARY
51-
echo "- Comment-Handling Regression (5 checks)" >> $GITHUB_STEP_SUMMARY
52-
echo "- Excluded Phases (3 checks)" >> $GITHUB_STEP_SUMMARY
53-
echo "- Numeric Type Preservation (6 checks)" >> $GITHUB_STEP_SUMMARY
54-
echo "- Inline Comments (2 checks)" >> $GITHUB_STEP_SUMMARY
56+
echo "### Test Suites (130 checks):" >> $GITHUB_STEP_SUMMARY
57+
echo "- Suite 1: V1 Generate → Parse Roundtrip" >> $GITHUB_STEP_SUMMARY
58+
echo "- Suite 2: Comment-Handling Regression" >> $GITHUB_STEP_SUMMARY
59+
echo "- Suite 3: Excluded Phases" >> $GITHUB_STEP_SUMMARY
60+
echo "- Suite 4: Numeric Type Preservation" >> $GITHUB_STEP_SUMMARY
61+
echo "- Suite 5: Inline Comments" >> $GITHUB_STEP_SUMMARY
62+
echo "- Suite 6: V2 Simple Backlight (plugin parsing)" >> $GITHUB_STEP_SUMMARY
63+
echo "- Suite 7: V2 Full Experiment (9 conditions, camera+backlight)" >> $GITHUB_STEP_SUMMARY
64+
echo "- Suite 8: V2 All Possible Plugins (serial, class, script)" >> $GITHUB_STEP_SUMMARY
65+
echo "- Suite 9: V2 Generate → Parse Roundtrip (plugins+params)" >> $GITHUB_STEP_SUMMARY
5566
echo "" >> $GITHUB_STEP_SUMMARY
5667
echo "### Generated Files:" >> $GITHUB_STEP_SUMMARY
57-
echo "- test_protocol_v1.yaml (for MATLAB validation)" >> $GITHUB_STEP_SUMMARY
58-
echo "- test_protocol_manifest.json (field expectations)" >> $GITHUB_STEP_SUMMARY
68+
echo "- test_protocol_v1.yaml + manifest (legacy)" >> $GITHUB_STEP_SUMMARY
69+
echo "- test_protocol_v2.yaml + manifest (plugins, multi-command conditions)" >> $GITHUB_STEP_SUMMARY
5970
echo "" >> $GITHUB_STEP_SUMMARY
60-
echo "> **Note**: Full MATLAB-side validation requires local MATLAB." >> $GITHUB_STEP_SUMMARY
61-
echo "> Run \`validate_web_protocol_roundtrip.m\` in maDisplayTools for end-to-end verification." >> $GITHUB_STEP_SUMMARY
71+
echo "> **MATLAB validation (35 checks)**: Run locally with" >> $GITHUB_STEP_SUMMARY
72+
echo "> \`validate_web_protocol_roundtrip('v2')\` in maDisplayTools." >> $GITHUB_STEP_SUMMARY

CLAUDE.md

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -438,28 +438,68 @@ The following UI improvements were made on 2026-02-02 and need testing on GitHub
438438

439439
## Experiment Designer
440440

441-
### Architecture (v1 — 2026-02-10)
442-
- 3-zone layout: settings panel (280px left), condition editor (flex right), timeline (bottom strip)
443-
- Single `<script type="module">` importing from `js/arena-configs.js`
444-
- Custom YAML parser (`simpleYAMLParse`) — no external dependency required
445-
- Data model: `experiment` object with `experiment_info`, `arena_info`, `experiment_structure`, phases, and `conditions[]`
446-
447-
### YAML Export
448-
- Generates protocol v1 with `trialParams` command name
449-
- Empty pattern fields export as `allOff` controller command
450-
- Phase structure: one `trialParams` command + one `wait` command per phase
451-
- Conditions wrapped in `block.conditions[].commands[]`
441+
### Architecture (v0.6 — 2026-04-01)
442+
- 3-zone layout: settings panel (280px left), editor with tab bar (flex right), timeline (bottom strip)
443+
- Single `<script type="module">` importing from `js/arena-configs.js`, `js/protocol-yaml.js`, `js/plugin-registry.js`
444+
- Data model: `experiment` object with `experiment_info`, `arena_info`, `rig_path`, `plugins[]`, `experiment_structure`, phases with `commands[]`, and `conditions[]` with `commands[]`
445+
446+
### Shared Modules
447+
- **`js/protocol-yaml.js`** — YAML parser (`simpleYAMLParse` with inline comment stripping), v1/v2 generators, string helpers. Dual-export (window.ProtocolYAML + ES6 module). Used by HTML, both test files.
448+
- **`js/plugin-registry.js`** — Built-in plugin definitions (LEDControllerPlugin: 7 commands, BiasPlugin: 6 commands), controller command definitions (6 commands), lookup functions for dropdown population. Dual-export.
449+
450+
### Data Model (v2 commands)
451+
Conditions and phases use **command arrays** as the primary data model:
452+
```javascript
453+
condition = {
454+
id: "string",
455+
commands: [
456+
{ type: "plugin", plugin_name: "camera", command_name: "getTimestamp" },
457+
{ type: "controller", command_name: "trialParams", pattern: "...",
458+
duration: 10, mode: 2, frame_index: 1, frame_rate: 10, gain: 0 },
459+
{ type: "wait", duration: 3 },
460+
{ type: "plugin", plugin_name: "backlight", command_name: "setRedLEDPower",
461+
params: { power: 5, panel_num: 0, pattern: "1010" } },
462+
]
463+
}
464+
phase = { include: true/false, commands: [ ...same format... ] }
465+
experiment.plugins = [
466+
{ name: "backlight", type: "class", matlab: { class: "LEDControllerPlugin" }, config: { ... } },
467+
{ name: "camera", type: "class", matlab: { class: "BiasPlugin" }, config: { ... } }
468+
]
469+
experiment.rig_path = "./configs/rigs/test_rig_1.yaml"
470+
```
471+
Helper functions: `cmdFindTrialParams(commands)`, `condGetDuration(cond)`, `condGetPattern(cond)`, `phaseGetDuration(phase)`.
472+
473+
### YAML Export (v2)
474+
- Generates protocol v2 via `generateV2Protocol()` from `js/protocol-yaml.js`
475+
- `rig:` field replaces inline `arena_info`
476+
- `plugins:` section lists enabled plugins with class/config
477+
- Conditions export full command arrays including plugin commands with params
478+
- Phases export command arrays directly
479+
480+
### Editor Tabs
481+
Three tabs in the right panel, all views of the same data model:
482+
1. **Visual** — Command card editor with color-coded cards (green=controller, gray=wait, blue=plugin), inline field editing, "Add Command" dropdown from plugin registry
483+
2. **Table** — Spreadsheet view with collapsible sections (pretrial, conditions with ITI, posttrial), type badges, param display
484+
3. **Timeline** — SVG multi-lane visualization per condition: controller spans, plugin event markers, wait bars, time axis. Read-only with hover tooltips.
452485

453486
### Key Implementation Notes
454-
- **Must use `<script type="module">`** to import `arena-configs.js` (bare `export` at end breaks regular `<script>` tags — this caused the initial "+ Add Condition" bug)
487+
- **Must use `<script type="module">`** to import shared modules
455488
- Mode 2 (Constant Rate): `gain` fixed at 0, `frame_rate` editable
456489
- Mode 4 (Closed-Loop): `frame_rate` fixed at 0, `gain` editable
457-
- All 7 trial parameters always included regardless of mode
490+
- `handleTrackClick` must explicitly call `renderTimelineView()` and `renderTableView()` after `renderEditor()` to keep all tabs in sync
491+
- Timeline `computeLaneData()`: trialParams fires controller autonomously (doesn't advance clock), wait advances clock, plugin commands are instantaneous
458492

459493
### Related Files
460-
- `experiment_designer.html` — Main tool
494+
- `experiment_designer.html` — Main tool (v0.6)
461495
- `experiment_designer_quickstart.html` — Step-by-step guide
462-
- `examples/simple_optomotor_protocol.yaml` — Test protocol
496+
- `js/protocol-yaml.js` — Shared YAML parser/generator
497+
- `js/plugin-registry.js` — Plugin definitions + command schemas
498+
- `tests/test-protocol-roundtrip.js` — 130 CI checks (9 suites, v1+v2)
499+
- `tests/generate-roundtrip-protocol.js` — YAML + manifest generator for MATLAB
500+
- `tests/fixtures/v2_*.yaml` — V2 YAML test fixtures from maDisplayTools
501+
- `docs/experiment-designer-v06-testing.md` — Manual testing checklist
502+
- `docs/protocol-roundtrip-testing.md` — Roundtrip testing architecture
463503
- GitHub Issue: [#33](https://github.com/reiserlab/webDisplayTools/issues/33)
464504

465505
## Planning Best Practices

0 commit comments

Comments
 (0)