feat: Add Study Insights module (SYS_16) for physics visualizations
Introduces a new plugin architecture for study-specific physics visualizations, separating "optimizer perspective" (Analysis) from "engineer perspective" (Insights). New module: optimization_engine/insights/ - base.py: StudyInsight base class, InsightConfig, InsightResult, registry - zernike_wfe.py: Mirror WFE with 3D surface and Zernike decomposition - stress_field.py: Von Mises stress contours with safety factors - modal_analysis.py: Natural frequencies and mode shapes - thermal_field.py: Temperature distribution visualization - design_space.py: Parameter-objective landscape exploration Features: - 5 insight types: zernike_wfe, stress_field, modal, thermal, design_space - CLI: python -m optimization_engine.insights generate <study> - Standalone HTML generation with Plotly - Enhanced Zernike viz: Turbo colorscale, smooth shading, 0.5x AMP - Dashboard API fix: Added include_coefficients param to extract_relative() Documentation: - docs/protocols/system/SYS_16_STUDY_INSIGHTS.md - Updated ATOMIZER_CONTEXT.md (v1.7) - Updated 01_CHEATSHEET.md with insights section Tools: - tools/zernike_html_generator.py: Standalone WFE HTML generator - tools/analyze_wfe.bat: Double-click to analyze OP2 files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -656,7 +656,8 @@ class ZernikeExtractor:
|
||||
def extract_relative(
|
||||
self,
|
||||
target_subcase: str,
|
||||
reference_subcase: str
|
||||
reference_subcase: str,
|
||||
include_coefficients: bool = False
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Extract Zernike metrics relative to a reference subcase.
|
||||
@@ -666,6 +667,7 @@ class ZernikeExtractor:
|
||||
Args:
|
||||
target_subcase: Subcase to analyze
|
||||
reference_subcase: Reference subcase to subtract
|
||||
include_coefficients: Whether to include all Zernike coefficients
|
||||
|
||||
Returns:
|
||||
Dict with relative RMS metrics and aberrations
|
||||
@@ -711,7 +713,7 @@ class ZernikeExtractor:
|
||||
)
|
||||
aberrations = compute_aberration_magnitudes(rms_result['coefficients'])
|
||||
|
||||
return {
|
||||
result = {
|
||||
'target_subcase': target_subcase,
|
||||
'reference_subcase': reference_subcase,
|
||||
'relative_global_rms_nm': rms_result['global_rms_nm'],
|
||||
@@ -721,6 +723,12 @@ class ZernikeExtractor:
|
||||
**{f'relative_{k}': v for k, v in aberrations.items()}
|
||||
}
|
||||
|
||||
if include_coefficients:
|
||||
result['coefficients'] = rms_result['coefficients'].tolist()
|
||||
result['coefficient_labels'] = [zernike_label(j) for j in range(1, self.n_modes + 1)]
|
||||
|
||||
return result
|
||||
|
||||
def extract_all_subcases(
|
||||
self,
|
||||
reference_subcase: Optional[str] = '20'
|
||||
|
||||
Reference in New Issue
Block a user