# Generate Report Skill **Last Updated**: December 3, 2025 **Version**: 1.1 - Optimization Results Analysis and Reporting (Dashboard Integration) You are helping the user understand and communicate optimization results. ## Purpose Generate comprehensive reports from completed optimization studies: 1. Pareto front analysis and visualization 2. Design space exploration insights 3. Constraint satisfaction analysis 4. Engineering recommendations 5. Export-ready summaries ## Triggers - "generate report" - "show results" - "analyze the optimization" - "what did we find?" - "summarize the study" - "export results" ## Prerequisites - Completed optimization study with `study.db` - At least 10 completed trials (for meaningful analysis) - Optional: `optimization_config.json` for context ## Report Types ### 1. Quick Summary Fast overview of key findings (default). ### 2. Full Technical Report Comprehensive analysis with all visualizations. ### 3. Executive Summary High-level findings for stakeholders. ### 4. Export Package Data files for external analysis. ## Execution Steps ### Step 1: Load Study Data ```python import optuna import json from pathlib import Path def load_study_data(study_name: str): """Load all optimization data for analysis.""" study_dir = Path(f"studies/{study_name}") # Load Optuna study storage = f"sqlite:///{study_dir / '2_results' / 'study.db'}" study = optuna.load_study(study_name=study_name, storage=storage) # Load config for context config_path = study_dir / "1_setup" / "optimization_config.json" config = json.loads(config_path.read_text()) if config_path.exists() else {} return { 'study': study, 'config': config, 'n_trials': len(study.trials), 'n_completed': len([t for t in study.trials if t.state == optuna.trial.TrialState.COMPLETE]), 'is_multi_objective': len(study.directions) > 1 } ``` ### Step 2: Analyze Results #### For Multi-Objective (Pareto Analysis) ```python def analyze_pareto_front(study): """Extract and analyze Pareto-optimal solutions.""" pareto_trials = study.best_trials results = { 'n_pareto': len(pareto_trials), 'designs': [], 'ranges': {}, 'trade_offs': [] } for trial in pareto_trials: design = { 'trial_number': trial.number, 'objectives': trial.values, 'parameters': trial.params, 'user_attrs': trial.user_attrs } results['designs'].append(design) # Calculate objective ranges on Pareto front if pareto_trials: obj_names = ['mass', 'frequency'] # From config for i, name in enumerate(obj_names): values = [t.values[i] for t in pareto_trials] results['ranges'][name] = { 'min': min(values), 'max': max(values), 'spread': max(values) - min(values) } return results ``` #### For Single-Objective ```python def analyze_single_objective(study): """Analyze single-objective optimization results.""" best = study.best_trial return { 'best_value': best.value, 'best_params': best.params, 'convergence': get_convergence_history(study), 'improvement_rate': calculate_improvement_rate(study) } ``` ### Step 3: Constraint Analysis ```python def analyze_constraints(study, config): """Analyze constraint satisfaction across trials.""" constraints = config.get('constraints', []) results = { 'total_trials': len(study.trials), 'feasible': 0, 'infeasible': 0, 'violations': {} } for constraint in constraints: results['violations'][constraint['name']] = 0 for trial in study.trials: if trial.state != optuna.trial.TrialState.COMPLETE: continue is_feasible = trial.user_attrs.get('feasible', True) if is_feasible: results['feasible'] += 1 else: results['infeasible'] += 1 # Track which constraints were violated for constraint in constraints: if constraint['name'] in trial.user_attrs.get('violated_constraints', []): results['violations'][constraint['name']] += 1 results['feasibility_rate'] = results['feasible'] / results['total_trials'] * 100 return results ``` ### Step 4: Generate Visualizations Describe what plots to generate (actual generation done via Python scripts): 1. **Pareto Front Plot**: Mass vs Frequency with feasibility coloring 2. **Parallel Coordinates**: All design variables with objective coloring 3. **Parameter Importance**: Which variables most affect objectives 4. **Convergence History**: Best value over trials 5. **Design Space Coverage**: Parameter distributions ### Step 5: Generate Report Text ## Output Format: Quick Summary ``` OPTIMIZATION RESULTS: {study_name} =================================== Study Info: Protocol: Protocol 11 (Multi-Objective NSGA-II) Trials: 30 completed Duration: 14m 23s Feasibility Rate: 80% PARETO FRONT (8 optimal designs) -------------------------------- | # | Mass (g) | Freq (Hz) | Feasible | Notes | |---|----------|-----------|----------|-------| | 1 | 231 | 118 | Yes | Lightest | | 2 | 248 | 128 | Yes | | | 3 | 265 | 138 | Yes | Balanced | | 4 | 282 | 148 | Yes | | | 5 | 298 | 156 | Yes | Stiffest | Trade-off Summary: - Mass range: 231g - 298g (67g spread) - Frequency range: 118Hz - 156Hz (38Hz spread) - Trade-off rate: ~1.7g per Hz BEST DESIGNS BY OBJECTIVE ------------------------- Lightest Design (#1): Mass: 231g, Frequency: 118Hz Parameters: beam_half_core_thickness: 8.2mm beam_face_thickness: 1.1mm holes_diameter: 42mm hole_count: 10 Stiffest Design (#5): Mass: 298g, Frequency: 156Hz Parameters: beam_half_core_thickness: 18.5mm beam_face_thickness: 2.8mm holes_diameter: 22mm hole_count: 6 CONSTRAINT ANALYSIS ------------------- Constraints checked: - max_displacement < 5mm: 24/30 satisfied (80%) - max_stress < 200 MPa: 28/30 satisfied (93%) Most common violation: Displacement (6 trials) Occurred when: holes_diameter > 40mm AND face_thickness < 1.5mm PARAMETER INSIGHTS ------------------ Most influential on mass: 1. holes_diameter (negative correlation) 2. beam_face_thickness (positive) 3. beam_half_core_thickness (positive) Most influential on frequency: 1. beam_half_core_thickness (positive) 2. holes_diameter (negative) 3. beam_face_thickness (moderate positive) RECOMMENDATIONS --------------- 1. For lightweight priority: - Use larger holes (40-45mm) - Minimize face thickness (1.0-1.5mm) - Accept frequency around 120Hz 2. For stiffness priority: - Use smaller holes (20-25mm) - Increase core thickness (18-20mm) - Accept mass around 300g 3. Balanced recommendation: - Design #3 offers good compromise - 265g mass with 138Hz frequency - 13% lighter than stiffest, 17% stiffer than lightest NEXT STEPS ---------- 1. Export selected designs: python export_pareto.py --designs 1,3,5 2. Validate in NX: Open model with exported parameters 3. Continue optimization: python run_optimization.py --trials 50 --resume 4. Enable NN acceleration: Add --enable-nn flag for faster exploration ``` ## Output Format: Full Technical Report Generate markdown file with: ```markdown # {study_name} Optimization Report Generated: {timestamp} Protocol: {protocol} ## Executive Summary [2-3 paragraph overview] ## Study Configuration ### Design Variables [Table of variables, bounds, types] ### Objectives [Table of objectives, goals, targets] ### Constraints [Table of constraints, thresholds] ## Results Analysis ### Pareto Front [Detailed table of all Pareto-optimal designs] ![Pareto Front](pareto_front.png) ### Design Space Exploration [Parallel coordinates plot] ![Parallel Coordinates](parallel_coords.png) ### Convergence History [Plot of best values over trials] ### Parameter Importance [SHAP or importance analysis] ## Constraint Satisfaction [Detailed constraint analysis] ## Engineering Recommendations [Specific design recommendations] ## Appendix ### All Trial Data [Exportable CSV reference] ### Methodology Notes [Protocol details, sampler settings] ``` ## Export Package Generate files: ``` {study_name}_export/ ├── pareto_designs.csv # All Pareto-optimal designs ├── all_trials.csv # Complete trial history ├── optimization_summary.json # Machine-readable summary ├── pareto_front.png # Visualization ├── parallel_coords.png # Visualization └── README.md # Export documentation ``` ## Error Handling | Error | Recovery | |-------|----------| | No completed trials | Suggest running more trials | | No feasible designs | Analyze constraint violations | | Study not found | List available studies | | Incomplete data | Note missing fields | ## Integration with Other Skills - After report → `/export-results` for specific designs - If poor results → `/troubleshoot` for analysis - To continue → `/run-optimization` with --resume ## Example Conversation ``` USER: Show me the results for uav_arm_optimization CLAUDE: I'll generate a report for the UAV arm optimization study... [Loads study data] OPTIMIZATION RESULTS: uav_arm_optimization ========================================== Found 30 completed trials with 8 Pareto-optimal designs. PARETO FRONT SUMMARY -------------------- | Design | Mass (g) | Freq (Hz) | Trade-off | |--------|----------|-----------|-----------| | #1 | 231 | 118 | Lightest | | #3 | 265 | 138 | Balanced | | #5 | 298 | 156 | Stiffest | Key Finding: You can save 67g (23%) by accepting 38Hz (24%) lower frequency. RECOMMENDATION: Design #3 (265g, 138Hz) offers the best balance for a camera gimbal application where both vibration and weight matter. Would you like me to: 1. Generate a full technical report with visualizations? 2. Export the top designs for validation in NX? 3. Continue optimization to explore more designs? ``` ## Dashboard Integration (December 2025) When a STUDY_REPORT.md file is generated, it can be viewed directly in the Atomizer Dashboard: 1. **Save report to**: `studies/{study_name}/STUDY_REPORT.md` (study root folder) 2. **View in dashboard**: Click "Study Report" button on the dashboard 3. **Features**: - Full markdown rendering with proper typography - Math equation support via KaTeX (`$...$` inline, `$$...$$` block) - Tables, code blocks, task lists - Live refresh button for updates during analysis ### Report Format for Dashboard Use standard markdown with optional LaTeX math: ```markdown # Study Report: {study_name} ## Summary The optimization achieved a **{improvement}%** improvement in objective. ## Results | Trial | Objective | Improvement | |-------|-----------|-------------| | 0 | 100.0 | baseline | | 10 | 85.5 | 14.5% | ## Mathematical Formulation The RMS wavefront error is calculated as: $$\text{RMS} = \sqrt{\frac{1}{N}\sum_{i=1}^{N}c_i^2}$$ where $c_i$ are the Zernike coefficients. ``` ## Notes - Reports should be actionable, not just data dumps - Always provide engineering context and recommendations - Consider the user's stated goals when highlighting results - Visualizations should be generated via Python scripts - Export formats should be compatible with common tools (Excel, etc.) - **Use STUDY_REPORT.md** for dashboard-viewable reports with math support