# SYS_13: Real-Time Dashboard Tracking

<!--
PROTOCOL: Real-Time Dashboard Tracking
LAYER: System
VERSION: 1.0
STATUS: Active
LAST_UPDATED: 2025-12-05
PRIVILEGE: user
LOAD_WITH: [SYS_10_IMSO, SYS_11_MULTI_OBJECTIVE]
-->

## Overview

Protocol 13 implements a comprehensive real-time web dashboard for monitoring optimization studies. It provides live visualization of optimizer state, Pareto fronts, parallel coordinates, and trial history with automatic updates every trial.

**Key Feature**: Every trial completion writes state to JSON, enabling live browser updates.

---

## When to Use

| Trigger | Action |
|---------|--------|
| "dashboard", "visualization" mentioned | Load this protocol |
| "real-time", "monitoring" requested | Enable dashboard tracking |
| Multi-objective study | Dashboard shows Pareto front |
| Want to see progress visually | Point to `localhost:3000` |

---

## Quick Reference

**Dashboard URLs**:
| Service | URL | Purpose |
|---------|-----|---------|
| Frontend | `http://localhost:3000` | Main dashboard |
| Backend API | `http://localhost:8000` | REST API |
| Optuna Dashboard | `http://localhost:8080` | Alternative viewer |

**Start Commands**:
```bash
# Backend
cd atomizer-dashboard/backend
python -m uvicorn api.main:app --reload --port 8000

# Frontend
cd atomizer-dashboard/frontend
npm run dev
```

---

## Architecture

```
Trial Completion (Optuna)
         │
         ▼
Realtime Callback (optimization_engine/realtime_tracking.py)
         │
         ▼
Write optimizer_state.json
         │
         ▼
Backend API /optimizer-state endpoint
         │
         ▼
Frontend Components (2s polling)
         │
         ▼
User sees live updates in browser
```

---

## Backend Components

### 1. Real-Time Tracking System (`realtime_tracking.py`)

**Purpose**: Write JSON state files after every trial completion.

**Integration** (in `intelligent_optimizer.py`):
```python
from optimization_engine.realtime_tracking import create_realtime_callback

# Create callback
callback = create_realtime_callback(
    tracking_dir=results_dir / "intelligent_optimizer",
    optimizer_ref=self,
    verbose=True
)

# Register with Optuna
study.optimize(objective, n_trials=n_trials, callbacks=[callback])
```

**Data Structure** (`optimizer_state.json`):
```json
{
  "timestamp": "2025-11-21T15:27:28.828930",
  "trial_number": 29,
  "total_trials": 50,
  "current_phase": "adaptive_optimization",
  "current_strategy": "GP_UCB",
  "is_multi_objective": true,
  "study_directions": ["maximize", "minimize"]
}
```

### 2. REST API Endpoints

**Base**: `/api/optimization/studies/{study_id}/`

| Endpoint | Method | Returns |
|----------|--------|---------|
| `/metadata` | GET | Objectives, design vars, constraints with units |
| `/optimizer-state` | GET | Current phase, strategy, progress |
| `/pareto-front` | GET | Pareto-optimal solutions (multi-objective) |
| `/history` | GET | All trial history |
| `/` | GET | List all studies |

**Unit Inference**:
```python
def _infer_objective_unit(objective: Dict) -> str:
    name = objective.get("name", "").lower()
    desc = objective.get("description", "").lower()

    if "frequency" in name or "hz" in desc:
        return "Hz"
    elif "stiffness" in name or "n/mm" in desc:
        return "N/mm"
    elif "mass" in name or "kg" in desc:
        return "kg"
    # ... more patterns
```

---

## Frontend Components

### 1. OptimizerPanel (`components/OptimizerPanel.tsx`)

**Displays**:
- Current phase (Characterization, Exploration, Exploitation, Adaptive)
- Current strategy (TPE, GP, NSGA-II, etc.)
- Progress bar with trial count
- Multi-objective indicator

```
┌─────────────────────────────────┐
│ Intelligent Optimizer Status    │
├─────────────────────────────────┤
│ Phase: [Adaptive Optimization]  │
│ Strategy: [GP_UCB]              │
│ Progress: [████████░░] 29/50    │
│ Multi-Objective: ✓              │
└─────────────────────────────────┘
```

### 2. ParetoPlot (`components/ParetoPlot.tsx`)

**Features**:
- Scatter plot of Pareto-optimal solutions
- Pareto front line connecting optimal points
- **3 Normalization Modes**:
  - **Raw**: Original engineering values
  - **Min-Max**: Scales to [0, 1]
  - **Z-Score**: Standardizes to mean=0, std=1
- Tooltip shows raw values regardless of normalization
- Color-coded: green=feasible, red=infeasible

### 3. ParallelCoordinatesPlot (`components/ParallelCoordinatesPlot.tsx`)

**Features**:
- High-dimensional visualization (objectives + design variables)
- Interactive trial selection
- Normalized [0, 1] axes
- Color coding: green (feasible), red (infeasible), yellow (selected)

```
Stiffness    Mass    support_angle    tip_thickness
   │          │            │                │
   │    ╱─────╲           ╱                 │
   │   ╱       ╲─────────╱                  │
   │  ╱                  ╲                  │
```

### 4. Dashboard Layout

```
┌──────────────────────────────────────────────────┐
│ Study Selection                                  │
├──────────────────────────────────────────────────┤
│ Metrics Grid (Best, Avg, Trials, Pruned)        │
├──────────────────────────────────────────────────┤
│ [OptimizerPanel]  [ParetoPlot]                  │
├──────────────────────────────────────────────────┤
│ [ParallelCoordinatesPlot - Full Width]          │
├──────────────────────────────────────────────────┤
│ [Convergence]     [Parameter Space]             │
├──────────────────────────────────────────────────┤
│ [Recent Trials Table]                            │
└──────────────────────────────────────────────────┘
```

---

## Configuration

**In `optimization_config.json`**:
```json
{
  "dashboard_settings": {
    "enabled": true,
    "port": 8000,
    "realtime_updates": true
  }
}
```

**Study Requirements**:
- Must use Protocol 10 (IntelligentOptimizer) for optimizer state
- Must have `optimization_config.json` with objectives and design_variables
- Real-time tracking enabled automatically with Protocol 10

---

## Usage Workflow

### 1. Start Dashboard

```bash
# Terminal 1: Backend
cd atomizer-dashboard/backend
python -m uvicorn api.main:app --reload --port 8000

# Terminal 2: Frontend
cd atomizer-dashboard/frontend
npm run dev
```

### 2. Start Optimization

```bash
cd studies/my_study
conda activate atomizer
python run_optimization.py --n-trials 50
```

### 3. View Dashboard

- Open browser to `http://localhost:3000`
- Select study from dropdown
- Watch real-time updates every trial

### 4. Interact with Plots

- Toggle normalization on Pareto plot
- Click lines in parallel coordinates to select trials
- Hover for detailed trial information

---

## Performance

| Metric | Value |
|--------|-------|
| Backend endpoint latency | ~10ms |
| Frontend polling interval | 2 seconds |
| Real-time write overhead | <5ms per trial |
| Dashboard initial load | <500ms |

---

## Integration with Other Protocols

### Protocol 10 Integration
- Real-time callback integrated into `IntelligentOptimizer.optimize()`
- Tracks phase transitions (characterization → adaptive optimization)
- Reports strategy changes

### Protocol 11 Integration
- Pareto front endpoint checks `len(study.directions) > 1`
- Dashboard conditionally renders Pareto plots
- Uses Optuna's `study.best_trials` for Pareto front

---

## Troubleshooting

| Symptom | Cause | Solution |
|---------|-------|----------|
| "No Pareto front data yet" | Single-objective or no trials | Wait for trials, check objectives |
| OptimizerPanel shows "Not available" | Not using Protocol 10 | Enable IntelligentOptimizer |
| Units not showing | Missing unit in config | Add `unit` field or use pattern in description |
| Dashboard not updating | Backend not running | Start backend with uvicorn |
| CORS errors | Backend/frontend mismatch | Check ports, restart both |

---

## Cross-References

- **Depends On**: [SYS_10_IMSO](./SYS_10_IMSO.md), [SYS_11_MULTI_OBJECTIVE](./SYS_11_MULTI_OBJECTIVE.md)
- **Used By**: [OP_03_MONITOR_PROGRESS](../operations/OP_03_MONITOR_PROGRESS.md)
- **See Also**: Optuna Dashboard for alternative visualization

---

## Implementation Files

**Backend**:
- `atomizer-dashboard/backend/api/main.py` - FastAPI app
- `atomizer-dashboard/backend/api/routes/optimization.py` - Endpoints
- `optimization_engine/realtime_tracking.py` - Callback system

**Frontend**:
- `atomizer-dashboard/frontend/src/pages/Dashboard.tsx` - Main page
- `atomizer-dashboard/frontend/src/components/OptimizerPanel.tsx`
- `atomizer-dashboard/frontend/src/components/ParetoPlot.tsx`
- `atomizer-dashboard/frontend/src/components/ParallelCoordinatesPlot.tsx`

---

## Implementation Details

### Backend API Example (FastAPI)

```python
@router.get("/studies/{study_id}/pareto-front")
async def get_pareto_front(study_id: str):
    """Get Pareto-optimal solutions for multi-objective studies."""
    study = optuna.load_study(study_name=study_id, storage=storage)

    if len(study.directions) == 1:
        return {"is_multi_objective": False}

    return {
        "is_multi_objective": True,
        "pareto_front": [
            {
                "trial_number": t.number,
                "values": t.values,
                "params": t.params,
                "user_attrs": dict(t.user_attrs)
            }
            for t in study.best_trials
        ]
    }
```

### Frontend OptimizerPanel (React/TypeScript)

```typescript
export function OptimizerPanel({ studyId }: { studyId: string }) {
  const [state, setState] = useState<OptimizerState | null>(null);

  useEffect(() => {
    const fetchState = async () => {
      const res = await fetch(`/api/optimization/studies/${studyId}/optimizer-state`);
      setState(await res.json());
    };
    fetchState();
    const interval = setInterval(fetchState, 1000);
    return () => clearInterval(interval);
  }, [studyId]);

  return (
    <Card title="Optimizer Status">
      <div>Phase: {state?.current_phase}</div>
      <div>Strategy: {state?.current_strategy}</div>
      <ProgressBar value={state?.trial_number} max={state?.total_trials} />
    </Card>
  );
}
```

### Callback Integration

**CRITICAL**: Every `study.optimize()` call must include the realtime callback:

```python
# In IntelligentOptimizer
self.realtime_callback = create_realtime_callback(
    tracking_dir=self.tracking_dir,
    optimizer_ref=self,
    verbose=self.verbose
)

# Register with ALL optimize calls
self.study.optimize(
    objective_function,
    n_trials=check_interval,
    callbacks=[self.realtime_callback]  # Required for real-time updates
)
```

---

## Chart Library Options

The dashboard supports two chart libraries:

| Feature | Recharts | Plotly |
|---------|----------|--------|
| Load Speed | Fast | Slower (lazy loaded) |
| Interactivity | Basic | Advanced |
| Export | Screenshot | PNG/SVG native |
| 3D Support | No | Yes |
| Real-time Updates | Better | Good |

**Recommendation**: Use Recharts during active optimization, Plotly for post-analysis.

### Quick Start

```bash
# Both backend and frontend
python start_dashboard.py

# Or manually:
cd atomizer-dashboard/backend && python -m uvicorn main:app --port 8000
cd atomizer-dashboard/frontend && npm run dev
```

Access at: `http://localhost:3003`

---

## Version History

| Version | Date | Changes |
|---------|------|---------|
| 1.2 | 2025-12-05 | Added chart library options |
| 1.1 | 2025-12-05 | Added implementation code snippets |
| 1.0 | 2025-11-21 | Initial release with real-time tracking |
