Neural Acceleration (MLP Surrogate): - Add run_nn_optimization.py with hybrid FEA/NN workflow - MLP architecture: 4-layer (64->128->128->64) with BatchNorm/Dropout - Three workflow modes: - --all: Sequential export->train->optimize->validate - --hybrid-loop: Iterative Train->NN->Validate->Retrain cycle - --turbo: Aggressive single-best validation (RECOMMENDED) - Turbo mode: 5000 NN trials + 50 FEA validations in ~12 minutes - Separate nn_study.db to avoid overloading dashboard Performance Results (bracket_pareto_3obj study): - NN prediction errors: mass 1-5%, stress 1-4%, stiffness 5-15% - Found minimum mass designs at boundary (angle~30deg, thick~30mm) - 100x speedup vs pure FEA exploration Protocol Operating System: - Add .claude/skills/ with Bootstrap, Cheatsheet, Context Loader - Add docs/protocols/ with operations (OP_01-06) and system (SYS_10-14) - Update SYS_14_NEURAL_ACCELERATION.md with MLP Turbo Mode docs NX Automation: - Add optimization_engine/hooks/ for NX CAD/CAE automation - Add study_wizard.py for guided study creation - Fix FEM mesh update: load idealized part before UpdateFemodel() New Study: - bracket_pareto_3obj: 3-objective Pareto (mass, stress, stiffness) - 167 FEA trials + 5000 NN trials completed - Demonstrates full hybrid workflow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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 |
|