436 lines
12 KiB
Markdown
436 lines
12 KiB
Markdown
|
|
# 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 |
|