Documentation: - Add docs/06_PHYSICS/ with Zernike fundamentals and OPD method docs - Add docs/guides/CMA-ES_EXPLAINED.md optimization guide - Update CLAUDE.md and ATOMIZER_CONTEXT.md with current architecture - Update OP_01_CREATE_STUDY protocol Planning: - Add DYNAMIC_RESPONSE plans for random vibration/PSD support - Add OPTIMIZATION_ENGINE_MIGRATION_PLAN for code reorganization Insights System: - Update design_space, modal_analysis, stress_field, thermal_field insights - Improve error handling and data validation NX Journals: - Add analyze_wfe_zernike.py for Zernike WFE analysis - Add capture_study_images.py for automated screenshots - Add extract_expressions.py and introspect_part.py utilities - Add user_generated_journals/journal_top_view_image_taking.py Tests & Tools: - Add comprehensive Zernike OPD test suite - Add audit_v10 tests for WFE validation - Add tools for Pareto graphs and mirror data extraction - Add migrate_studies_to_topics.py utility Knowledge Base: - Initialize LAC (Learning Atomizer Core) with failure/success patterns Dashboard: - Update Setup.tsx and launch_dashboard.py - Add restart-dev.bat helper script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
73 lines
2.7 KiB
Python
73 lines
2.7 KiB
Python
"""Compare V9 vs V10 calculation methods."""
|
|
import sys
|
|
from pathlib import Path
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from optimization_engine.extractors import ZernikeExtractor
|
|
|
|
op2 = Path('studies/M1_Mirror/m1_mirror_cost_reduction_V10/2_iterations/iter1/assy_m1_assyfem1_sim1-solution_1.op2')
|
|
extractor = ZernikeExtractor(op2, n_modes=50, filter_orders=4)
|
|
|
|
print("="*70)
|
|
print("CRITICAL: V9 vs V10 Calculation Method Comparison")
|
|
print("="*70)
|
|
print()
|
|
|
|
# This is what V9 does - computes relative WFE THEN fits Zernike
|
|
rel_40 = extractor.extract_relative('3', '2')
|
|
rel_60 = extractor.extract_relative('4', '2')
|
|
rel_90 = extractor.extract_relative('1', '2')
|
|
|
|
print('V9 method (ZernikeExtractor.extract_relative):')
|
|
print(' Computes WFE_diff = WFE_target - WFE_ref node-by-node')
|
|
print(' Then fits Zernike to WFE_diff')
|
|
print()
|
|
print(f' 40-20: {rel_40["relative_filtered_rms_nm"]:.2f} nm')
|
|
print(f' 60-20: {rel_60["relative_filtered_rms_nm"]:.2f} nm')
|
|
print(f' 90-20 (j1to3): {rel_90["relative_rms_filter_j1to3"]:.2f} nm')
|
|
|
|
# Individual absolute values
|
|
r20 = extractor.extract_subcase('2')
|
|
r40 = extractor.extract_subcase('3')
|
|
r60 = extractor.extract_subcase('4')
|
|
r90 = extractor.extract_subcase('1')
|
|
|
|
print()
|
|
print('='*70)
|
|
print('Individual absolute RMS values:')
|
|
print('='*70)
|
|
print(f' 20 deg: {r20["filtered_rms_nm"]:.2f} nm')
|
|
print(f' 40 deg: {r40["filtered_rms_nm"]:.2f} nm')
|
|
print(f' 60 deg: {r60["filtered_rms_nm"]:.2f} nm')
|
|
print(f' 90 deg: {r90["filtered_rms_nm"]:.2f} nm')
|
|
|
|
print()
|
|
print('='*70)
|
|
print('V10 method (WRONG - difference of RMS values):')
|
|
print(' Computes RMS_target - RMS_ref')
|
|
print(' This is NOT the same as RMS of the difference!')
|
|
print('='*70)
|
|
print()
|
|
print(f' 40-20: {r40["filtered_rms_nm"] - r20["filtered_rms_nm"]:.2f} nm')
|
|
print(f' 60-20: {r60["filtered_rms_nm"] - r20["filtered_rms_nm"]:.2f} nm')
|
|
print(f' After abs(): {abs(r40["filtered_rms_nm"] - r20["filtered_rms_nm"]):.2f} nm')
|
|
print(f' After abs(): {abs(r60["filtered_rms_nm"] - r20["filtered_rms_nm"]):.2f} nm')
|
|
|
|
print()
|
|
print('='*70)
|
|
print('CONCLUSION')
|
|
print('='*70)
|
|
print()
|
|
print('V10 BUG: Computes abs(RMS_target - RMS_ref) instead of RMS(WFE_target - WFE_ref)')
|
|
print()
|
|
print('The CORRECT relative WFE (from V9 method):')
|
|
print(f' 40-20: {rel_40["relative_filtered_rms_nm"]:.2f} nm')
|
|
print(f' 60-20: {rel_60["relative_filtered_rms_nm"]:.2f} nm')
|
|
print(f' 90-20: {rel_90["relative_rms_filter_j1to3"]:.2f} nm')
|
|
print()
|
|
print('The WRONG values V10 reports:')
|
|
print(f' 40-20: {abs(r40["filtered_rms_nm"] - r20["filtered_rms_nm"]):.2f} nm')
|
|
print(f' 60-20: {abs(r60["filtered_rms_nm"] - r20["filtered_rms_nm"]):.2f} nm')
|
|
print()
|
|
print('V10 values are ~3-4x LOWER than correct values!')
|