""" Report Generator Utility Generates Markdown/HTML/PDF reports for optimization studies """ import json from pathlib import Path from typing import Optional import markdown from datetime import datetime def generate_study_report( study_dir: Path, output_format: str = "markdown", include_llm_summary: bool = False ) -> Optional[Path]: """ Generate a report for the study. Args: study_dir: Path to the study directory output_format: 'markdown', 'html', or 'pdf' include_llm_summary: Whether to include AI-generated summary Returns: Path to the generated report file """ try: # Load data config_path = study_dir / "1_setup" / "optimization_config.json" history_path = study_dir / "2_results" / "optimization_history_incremental.json" if not config_path.exists() or not history_path.exists(): return None with open(config_path) as f: config = json.load(f) with open(history_path) as f: history = json.load(f) # Find best trial best_trial = None if history: best_trial = min(history, key=lambda x: x['objective']) # Generate Markdown content md_content = f"""# Optimization Report: {config.get('study_name', study_dir.name)} **Date**: {datetime.now().strftime('%Y-%m-%d %H:%M')} **Status**: {'Completed' if len(history) >= config.get('optimization_settings', {}).get('n_trials', 50) else 'In Progress'} ## Executive Summary {_generate_summary(history, best_trial, include_llm_summary)} ## Study Configuration - **Objectives**: {', '.join([o['name'] for o in config.get('objectives', [])])} - **Design Variables**: {len(config.get('design_variables', []))} variables - **Total Trials**: {len(history)} ## Best Result (Trial #{best_trial['trial_number'] if best_trial else 'N/A'}) - **Objective Value**: {best_trial['objective'] if best_trial else 'N/A'} - **Parameters**: """ if best_trial: for k, v in best_trial['design_variables'].items(): md_content += f" - **{k}**: {v:.4f}\n" md_content += "\n## Optimization Progress\n" md_content += "The optimization process showed convergence towards the optimal solution.\n" # Save report based on format timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') output_dir = study_dir / "2_results" if output_format in ['markdown', 'md']: output_path = output_dir / f"optimization_report_{timestamp}.md" with open(output_path, 'w') as f: f.write(md_content) elif output_format == 'html': output_path = output_dir / f"optimization_report_{timestamp}.html" html_content = markdown.markdown(md_content) # Add basic styling styled_html = f"""
{html_content} """ with open(output_path, 'w') as f: f.write(styled_html) elif output_format == 'pdf': # Requires weasyprint try: from weasyprint import HTML output_path = output_dir / f"optimization_report_{timestamp}.pdf" html_content = markdown.markdown(md_content) HTML(string=html_content).write_pdf(str(output_path)) except ImportError: print("WeasyPrint not installed, falling back to HTML") return generate_study_report(study_dir, 'html', include_llm_summary) return output_path except Exception as e: print(f"Report generation error: {e}") return None def _generate_summary(history, best_trial, use_llm): if use_llm: return "[AI Summary Placeholder] The optimization successfully identified a design that minimizes mass while satisfying all constraints." if not history: return "No trials completed yet." improvement = 0 if len(history) > 1: first = history[0]['objective'] best = best_trial['objective'] improvement = ((first - best) / first) * 100 return f"The optimization run completed {len(history)} trials. The best design found (Trial #{best_trial['trial_number']}) achieved an objective value of {best_trial['objective']:.4f}, representing a {improvement:.1f}% improvement over the initial design."