Skip to content

Latest commit

 

History

History
497 lines (387 loc) · 16.5 KB

File metadata and controls

497 lines (387 loc) · 16.5 KB

EEG Dipole Demo v2.0 - Implementation Plan

Executive Summary

This plan outlines a significant upgrade to transform the EEG Dipole Demo from a single-dipole educational tool into a research-grade forward modeling platform. The upgrade introduces:

  1. Blob Mode - Active region modeling with collective controls
  2. 3D Positioning - Full nasion-inion axis placement
  3. Time Series Drive - User-uploaded amplitude modulation
  4. Data Export - 10/20 electrode voltage time series output

Current Architecture Analysis

What Exists

  • Single HTML file (~2.4MB, mostly base64-encoded coronal brain image)
  • Coronal plane constraint - Dipoles fixed at y=0
  • Point dipole model - V ∝ (p · R) / |R|³
  • 19 electrodes - Standard 10-20 montage (Fp1, Fp2, F3, F4, F7, F8, Fz, T3, T4, C3, C4, Cz, T5, T6, P3, P4, Pz, O1, O2, Oz)
  • Two views - Coronal slice (x-z) + topographic map (x-y projected)
  • Real-time rendering - requestAnimationFrame loop

Coordinate System

        +z (superior/dorsal)
         |
         |    +y (anterior/nasion)
         |   /
         |  /
         | /
         +---------- +x (right)

Current: dipoles at y=0 (coronal plane)
Proposed: full y-axis movement (-1 to +1)

Feature Breakdown & Complexity Assessment

Feature 1: Blob Mode (Active Region)

Concept: Instead of placing individual point dipoles, users create a "blob" representing an active cortical patch. The blob contains multiple dipoles with coherent orientation.

Implementation Options:

Option Description Pros Cons
A. Gaussian Cluster 3D Gaussian distribution of dipole density Biologically plausible, smooth falloff Computationally heavier
B. Uniform Sphere Uniform dipole density within spherical region Simple, fast Sharp boundary unrealistic
C. Surface Patch Dipoles constrained to brain surface Most realistic Requires surface mesh

Recommended: Option A (Gaussian Cluster) - Good balance of realism and simplicity.

Blob Properties:

  • Position (x, y, z) - center of mass
  • Radius - σ parameter of Gaussian
  • Orientation (θ, φ) - direction of all dipoles in blob
  • Strength - total dipole moment magnitude
  • Dipole count - sampling density (affects accuracy vs. performance)

Complexity: MEDIUM

  • New data structure for blobs
  • Collective potential computation (sum N dipole contributions)
  • UI for blob radius, orientation dial
  • Visual representation (ellipsoid/cloud)

UI Changes:

Mode: [Single Dipole ↔ Blob Region] toggle

Blob Controls:
├── Radius slider: 0.05 - 0.3 (brain units)
├── Orientation dial: 0° - 360° (circular control)
├── Tilt slider: 0° - 90° (radial vs tangential)
├── Strength slider: 0.1 - 2.0
└── Resolution: [Low|Med|High] (dipole sampling)

Feature 2: Nasion-Inion Axis (Y-axis Positioning)

Current Limitation: All dipoles at y=0. User cannot place sources in frontal or occipital regions accurately.

Challenge: How to visualize and control the 3rd dimension?

Implementation Options:

Option Description Complexity User Experience
A. Y-Slider Only Simple slider for y-position LOW Limited spatial intuition
B. Sagittal View Add 3rd canvas showing x-y or y-z plane HIGH Full 3D understanding
C. 3D Rotation WebGL 3D head model VERY HIGH Best visualization
D. Hybrid Y-slider + topomap indicator MEDIUM Good balance

Recommended: Option D (Hybrid) initially, with Option B as a follow-up enhancement.

Hybrid Approach:

  1. Add Y-position slider to blob/dipole controls
  2. Show blob projection on topomap (circle at projected position)
  3. Topomap becomes partially 3D-aware (blob appears as dot/circle showing depth)
  4. Optional: Add sagittal slice view later

Brain Boundary in 3D:

  • Current: 2D mask from coronal image
  • Needed: 3D brain model (ellipsoid approximation or volumetric)

Simplified 3D Brain Model:

// Ellipsoid approximation
function inBrain3D(x, y, z) {
    const cx = 0, cy = 0, cz = -0.05; // center
    const rx = 0.75, ry = 0.80, rz = 0.70; // radii
    const dx = (x - cx) / rx;
    const dy = (y - cy) / ry;
    const dz = (z - cz) / rz;
    return (dx*dx + dy*dy + dz*dz) <= 1.0;
}

Complexity: MEDIUM-HIGH

  • Y-position control trivial
  • Visualization of depth requires thought
  • 3D brain constraint needs new model or volumetric data
  • Sagittal view (optional) requires new anatomical image

Feature 3: Time Series Upload

Concept: User uploads a file containing amplitude values over time. The blob's strength follows this time course during playback.

File Format Options:

Option A: Simple CSV
-----------------------
time,amplitude
0.000,0.0
0.001,0.23
0.002,0.45
...

Option B: Multi-channel CSV (for multiple blobs)
-------------------------------------------------
time,blob1,blob2,blob3
0.000,0.0,0.1,0.0
0.001,0.23,0.15,0.05
...

Option C: JSON with metadata
-----------------------------
{
  "sampleRate": 1000,
  "duration": 2.0,
  "channels": [
    {"name": "blob1", "data": [0.0, 0.23, 0.45, ...]},
    {"name": "blob2", "data": [0.1, 0.15, 0.12, ...]}
  ]
}

Recommended: Option B - Simple, standard, supports multiple blobs.

Playback System:

Timeline UI:
┌────────────────────────────────────────────┐
│ [▶] [⏸] [⏹] |░░░░░●░░░░░░░░░░░░░░| 0.523s │
│              [1x] [2x] [0.5x]              │
└────────────────────────────────────────────┘

Implementation:

  1. File input element with drag-drop support
  2. CSV parser (Papa Parse library or vanilla JS)
  3. Time series data structure
  4. Animation controller (playhead, speed, loop)
  5. Interpolation between samples (linear or cubic)
  6. Per-frame amplitude update to blob(s)

Complexity: MEDIUM

  • File upload: trivial
  • CSV parsing: simple (vanilla JS adequate)
  • Playback controls: standard pattern
  • Blob-to-channel mapping: needs UI
  • Performance: may need optimization for long recordings

Feature 4: Export Electrode Voltages

Concept: During time series playback, compute and export the voltage at each 10/20 electrode location.

Output Format:

time,Fp1,Fp2,F3,F4,F7,F8,Fz,T3,T4,C3,C4,Cz,T5,T6,P3,P4,Pz,O1,O2,Oz
0.000,-0.23,0.45,0.12,-0.08,...
0.001,-0.21,0.42,0.14,-0.09,...
...

Implementation:

  1. Pre-compute mode: calculate all frames before export
  2. Streaming mode: compute during playback, buffer results
  3. Export button triggers CSV download

Performance Consideration:

  • 20 electrodes × 1000 samples × N blobs × M dipoles/blob
  • For M=50 dipoles, N=1 blob, 1000 samples: 1M potential calculations
  • Should complete in <1 second on modern hardware

Complexity: LOW

  • Just data collection during playback
  • Standard CSV generation
  • Blob download mechanism

Potential Cumbersome Issues

1. 3D Brain Boundary Constraint

Problem: Current inBrain() uses 2D coronal mask. Moving to y-axis requires 3D.

Solutions:

  • Quick: Ellipsoid approximation (math-only, no new images)
  • Better: Volumetric mask from Allen Brain Atlas
  • Best: Load actual brain mesh for surface constraint

Recommendation: Start with ellipsoid, upgrade later if needed.

2. Multi-View Synchronization

Problem: If we add sagittal view, three views must stay synchronized.

Solution: Centralized state management:

const state = {
    blobs: [...],
    selectedBlobId: null,
    viewMode: 'coronal', // or 'sagittal', 'both'
    // ...
};

function updateViews() {
    drawCoronal(state);
    drawTopomap(state);
    if (state.viewMode === 'both') drawSagittal(state);
}

3. Time Series Playback Performance

Problem: Computing potentials at high frame rates with many dipoles could lag.

Solutions:

  • Precomputation: Calculate all frames upfront (blocking but predictable)
  • Web Workers: Offload computation to background thread
  • Adaptive sampling: Reduce dipole count in blobs during playback

Recommendation: Precomputation for recordings <10s, Web Workers for longer.

4. Allen Brain Atlas Integration

Problem: Atlas uses different coordinate systems (MNI, Allen CCF).

Solution: For this demo, use simplified models rather than true atlas coordinates. The unit sphere model is pedagogically cleaner.

Future Enhancement: Add coordinate transform option for advanced users.

5. Single-File vs. Multi-File Architecture

Problem: Current 2.4MB single file is already unwieldy. Adding features will make it worse.

Decision: Move to multi-file architecture.


Proposed File Architecture

EEG-Dipole-Demo/
├── index.html              # Main HTML structure
├── css/
│   └── styles.css          # All styles (extracted from inline)
├── js/
│   ├── main.js             # Entry point, initialization
│   ├── core/
│   │   ├── physics.js      # Potential calculations
│   │   ├── electrodes.js   # 10/20 electrode definitions
│   │   └── math.js         # Vector math utilities
│   ├── models/
│   │   ├── dipole.js       # Single dipole class
│   │   ├── blob.js         # Blob (active region) class
│   │   └── timeseries.js   # Time series data handling
│   ├── views/
│   │   ├── coronal.js      # Coronal canvas rendering
│   │   ├── topomap.js      # Topographic map rendering
│   │   └── sagittal.js     # (Future) Sagittal view
│   ├── ui/
│   │   ├── controls.js     # Slider/button bindings
│   │   ├── timeline.js     # Playback controls
│   │   ├── file-upload.js  # Time series file handling
│   │   └── dipole-list.js  # Dipole/blob list management
│   └── export/
│       └── csv.js          # CSV export functionality
├── assets/
│   ├── coronal-slice.png   # Brain image (extracted from base64)
│   └── sagittal-slice.png  # (Future) Sagittal brain image
└── README.md               # Updated documentation

Note: For users who need single-file deployment, we can provide a build script that bundles everything back into one file.


Implementation Phases

Phase 1: Architecture Refactor (Foundation)

Deliverables:

  • Extract code from monolithic HTML into modular JS files
  • Extract CSS into separate stylesheet
  • Extract brain image from base64 to PNG file
  • Set up simple build process (optional, for single-file output)
  • Verify existing functionality works

Risk: Breaking existing functionality during refactor. Mitigation: Comprehensive testing at each step.

Phase 2: Blob Mode

Deliverables:

  • Blob data structure and physics
  • Mode toggle (single dipole ↔ blob)
  • Blob controls (radius, orientation dial, strength)
  • Blob visualization in coronal view
  • Update topomap rendering for blob

Phase 3: Y-Axis Positioning

Deliverables:

  • Y-position slider for blobs
  • 3D ellipsoid brain constraint
  • Topomap depth indicator
  • (Optional) Basic sagittal view

Phase 4: Time Series Playback

Deliverables:

  • File upload UI (drag-drop CSV)
  • CSV parser
  • Timeline/playback controls
  • Blob amplitude modulation
  • Channel-to-blob mapping UI

Phase 5: Export System

Deliverables:

  • Voltage computation during playback
  • CSV export of electrode time series
  • Download button and file naming

Phase 6: Polish & Documentation

Deliverables:

  • UI/UX refinements
  • Error handling and validation
  • Updated README
  • Example time series files
  • Usage tutorial

Technical Decisions Required

Decision 1: Blob Dipole Distribution

Options:

  • A) Gaussian: density(r) = exp(-r²/2σ²)
  • B) Uniform sphere: density(r) = 1 if r < R else 0
  • C) Shell: dipoles on surface of sphere only

Recommendation: A (Gaussian) - most physically plausible.

Decision 2: Sagittal View Priority

Options:

  • A) Include in initial release
  • B) Defer to future version
  • C) Add as optional toggle

Recommendation: B or C - Y-slider + topomap indicator sufficient for v2.0.

Decision 3: Time Series Format

Options:

  • A) CSV only (simple)
  • B) CSV + JSON (flexible)
  • C) CSV + EDF/BDF support (clinical compatibility)

Recommendation: A for v2.0, with extensibility hooks for future formats.

Decision 4: Build System

Options:

  • A) No build (ES modules loaded directly)
  • B) Simple bundler (esbuild/rollup)
  • C) Full toolchain (webpack/vite)

Recommendation: A with optional B - ES modules work in modern browsers, bundler script for single-file output.


Estimated Scope

Phase Complexity Files Affected
Phase 1 (Refactor) HIGH All (rewrite)
Phase 2 (Blob Mode) MEDIUM models/blob.js, views/, ui/controls.js
Phase 3 (Y-Axis) MEDIUM models/, views/coronal.js, ui/controls.js
Phase 4 (Time Series) MEDIUM models/timeseries.js, ui/timeline.js, ui/file-upload.js
Phase 5 (Export) LOW export/csv.js, ui/controls.js
Phase 6 (Polish) LOW All (minor)

Open Questions for Discussion

  1. Blob shape: Should blobs always be spherical, or support ellipsoids for anisotropic activation?

  2. Multiple blobs: Should users be able to create multiple blobs simultaneously? (Increases complexity but useful for bilateral sources)

  3. Time series assignment: If multiple blobs exist, how should uploaded channels map to blobs? (Explicit mapping UI vs. automatic by order)

  4. Sagittal image source: Should we extract a sagittal slice from the same atlas as coronal, or use Allen Brain Atlas API?

  5. Offline mode: Should the multi-file architecture still support offline use? (Probably yes via bundling)

  6. Coordinate display: Should we show MNI coordinates or keep the abstract unit sphere system?


Next Steps

  1. Review this plan - Confirm approach and priorities
  2. Resolve open questions - Especially blob shape and multiple blob support
  3. Begin Phase 1 - Architecture refactor
  4. Iterative implementation - Phase by phase with testing

Implementation Progress

Phase 1: Architecture Refactor - ✅ COMPLETE

Files Created:

EEG-Dipole-Demo/
├── index.html              # New modular HTML (replaces monolith)
├── index-legacy.html       # Original single-file version (preserved)
├── css/
│   └── styles.css          # Extracted and enhanced styles
├── js/
│   ├── main.js             # Application entry point
│   ├── core/
│   │   ├── math.js         # Vector math, interpolation, Delaunay
│   │   ├── electrodes.js   # 10-20 electrode definitions
│   │   └── physics.js      # Potential calculations (dipole + blob)
│   ├── models/
│   │   ├── dipole.js       # Single dipole class
│   │   ├── blob.js         # Blob (active region) class
│   │   ├── timeseries.js   # Time series parsing and interpolation
│   │   └── state.js        # Centralized state management
│   ├── views/
│   │   ├── coronal.js      # Coronal canvas rendering
│   │   └── topomap.js      # Topographic map rendering
│   ├── ui/
│   │   ├── controls.js     # Source management UI
│   │   ├── timeline.js     # Playback controls
│   │   └── file-upload.js  # CSV upload handling
│   └── export/
│       └── csv.js          # CSV export functionality
└── assets/
    └── coronal-slice.png   # Extracted brain image (1536x1024)

Key Achievements:

  • Extracted 2.4MB base64 image to separate PNG file
  • Modularized JavaScript with ES6 modules
  • Centralized state management with pub/sub pattern
  • Blob model with Gaussian sampling implemented
  • Time series playback system implemented
  • Export system implemented
  • 3D brain boundary check (ellipsoid) implemented

Phases 2-5: Features - 🔄 IMPLEMENTED (awaiting testing)

All features were implemented as part of the architecture refactor:

  1. Blob Mode - Active regions with radius, strength, orientation
  2. Y-Axis Positioning - Slider for anterior-posterior placement
  3. Time Series Playback - CSV upload, channel mapping, timeline controls
  4. Export System - Static frame and full series export

Plan Version: 1.1 Updated: 2026-01-24 Status: Phase 1 Complete, Testing Needed