feat: Major update with validators, skills, dashboard, and docs reorganization
- Add validation framework (config, model, results, study validators) - Add Claude Code skills (create-study, run-optimization, generate-report, troubleshoot, analyze-model) - Add Atomizer Dashboard (React frontend + FastAPI backend) - Reorganize docs into structured directories (00-09) - Add neural surrogate modules and training infrastructure - Add multi-objective optimization support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -337,11 +337,18 @@ async def get_optimization_history(study_id: str, limit: Optional[int] = None):
|
||||
if not results and len(values) > 0:
|
||||
results["first_frequency"] = values[0]
|
||||
|
||||
# CRITICAL: Extract design_vars from user_attrs if stored there
|
||||
# The optimization code does: trial.set_user_attr("design_vars", design_vars)
|
||||
design_vars_from_attrs = user_attrs.get("design_vars", {})
|
||||
|
||||
# Merge with params (prefer user_attrs design_vars if available)
|
||||
final_design_vars = {**params, **design_vars_from_attrs} if design_vars_from_attrs else params
|
||||
|
||||
trials.append({
|
||||
"trial_number": trial_num,
|
||||
"objective": values[0] if len(values) > 0 else None, # Primary objective
|
||||
"objectives": values if len(values) > 1 else None, # All objectives for multi-objective
|
||||
"design_variables": params,
|
||||
"design_variables": final_design_vars, # Use merged design vars
|
||||
"results": results,
|
||||
"user_attrs": user_attrs, # Include all user attributes
|
||||
"start_time": start_time,
|
||||
@@ -679,6 +686,53 @@ async def get_mesh_file(study_id: str, filename: str):
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Failed to serve mesh file: {str(e)}")
|
||||
|
||||
@router.get("/studies/{study_id}/optuna-url")
|
||||
async def get_optuna_dashboard_url(study_id: str):
|
||||
"""
|
||||
Get the Optuna dashboard URL for a specific study.
|
||||
Returns the URL to access the study in Optuna dashboard.
|
||||
|
||||
The Optuna dashboard should be started with a relative path from the Atomizer root:
|
||||
sqlite:///studies/{study_id}/2_results/study.db
|
||||
"""
|
||||
try:
|
||||
study_dir = STUDIES_DIR / study_id
|
||||
if not study_dir.exists():
|
||||
raise HTTPException(status_code=404, detail=f"Study {study_id} not found")
|
||||
|
||||
results_dir = study_dir / "2_results"
|
||||
study_db = results_dir / "study.db"
|
||||
|
||||
if not study_db.exists():
|
||||
raise HTTPException(status_code=404, detail=f"No Optuna database found for study {study_id}")
|
||||
|
||||
# Get the study name from the database (may differ from folder name)
|
||||
import optuna
|
||||
storage = optuna.storages.RDBStorage(f"sqlite:///{study_db}")
|
||||
studies = storage.get_all_studies()
|
||||
|
||||
if not studies:
|
||||
raise HTTPException(status_code=404, detail=f"No Optuna study found in database for {study_id}")
|
||||
|
||||
# Use the actual study name from the database
|
||||
optuna_study_name = studies[0].study_name
|
||||
|
||||
# Return URL info for the frontend
|
||||
# The dashboard should be running on port 8081 with the correct database
|
||||
return {
|
||||
"study_id": study_id,
|
||||
"optuna_study_name": optuna_study_name,
|
||||
"database_path": f"studies/{study_id}/2_results/study.db",
|
||||
"dashboard_url": f"http://localhost:8081/dashboard/studies/{studies[0]._study_id}",
|
||||
"dashboard_base": "http://localhost:8081",
|
||||
"note": "Optuna dashboard must be started with: sqlite:///studies/{study_id}/2_results/study.db"
|
||||
}
|
||||
|
||||
except FileNotFoundError:
|
||||
raise HTTPException(status_code=404, detail=f"Study {study_id} not found")
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Failed to get Optuna URL: {str(e)}")
|
||||
|
||||
@router.post("/studies/{study_id}/generate-report")
|
||||
async def generate_report(
|
||||
study_id: str,
|
||||
|
||||
Reference in New Issue
Block a user