5.4 KiB
Handoff: Set Up Trajectory-Based Optimization for M1 Mirror
From: Mario (Clawdbot)
To: Claude (Windows/LAC)
Date: 2026-01-29
Context: M1 GigaBIT mirror optimization using new Zernike Trajectory Method
Summary
A new Zernike Trajectory extractor has been implemented and validated. It provides mode-specific optimization metrics (coma, astigmatism, trefoil, etc.) integrated across the full 20°-60° operating range instead of discrete weighted sums.
Your task: Set up an Atomizer optimization study using TPE optimizer with total_filtered_rms_nm as the primary objective, logging mode-specific metrics.
What's Already Done
- ✅ Extractor implemented:
optimization_engine/extractors/extract_zernike_trajectory.py - ✅ Validated on M1 model: R² = 1.0 (physics model confirmed)
- ✅ Documentation:
docs/physics/ZERNIKE_TRAJECTORY_METHOD.md - ✅ Example config:
docs/examples/trajectory_optimization_config.yaml
Pull latest from Gitea:
git pull origin main
What You Need to Set Up
1. Create New Study: SAT3_Trajectory
Location: studies/SAT3_Trajectory/ (or similar)
2. FEA Configuration
The FEA must solve 6 subcases with these elevation angles:
- 90° (manufacturing reference)
- 20° (measurement/polishing reference)
- 30° (new - for trajectory)
- 40° (primary operational)
- 50° (new - for trajectory)
- 60° (secondary operational)
Subcase labels in NX must be the angle numbers (e.g., LABEL = 20, LABEL = 40, etc.)
3. Extractor Configuration
Use the trajectory extractor:
extractors:
- id: ext_trajectory
name: "Zernike Trajectory"
type: zernike_trajectory
config:
reference_angle: 20.0
# Subcases auto-detected from OP2 labels
4. Objectives
Primary objective (what optimizer minimizes):
objectives:
- id: obj_total
name: "Total Integrated RMS"
source:
extractor_id: ext_trajectory
output_name: total_filtered_rms_nm
direction: minimize
weight: 1.0
Secondary objectives (logged but not optimized, weight=0):
- id: obj_coma
name: "Coma RMS"
source:
extractor_id: ext_trajectory
output_name: coma_rms_nm
direction: minimize
weight: 0.0
- id: obj_astig
name: "Astigmatism RMS"
source:
extractor_id: ext_trajectory
output_name: astigmatism_rms_nm
direction: minimize
weight: 0.0
- id: obj_trefoil
name: "Trefoil RMS"
source:
extractor_id: ext_trajectory
output_name: trefoil_rms_nm
direction: minimize
weight: 0.0
- id: obj_spherical
name: "Spherical RMS"
source:
extractor_id: ext_trajectory
output_name: spherical_rms_nm
direction: minimize
weight: 0.0
5. Optimizer Configuration
Use TPE (recommended for fresh start):
optimizer:
type: tpe
config:
n_trials: 100
n_startup_trials: 15
6. Constraints (Optional but Recommended)
constraints:
# Sanity check: linear model should fit well
- id: con_r2
name: "Trajectory fit quality"
source:
extractor_id: ext_trajectory
output_name: linear_fit_r2
type: soft
operator: ">="
threshold: 0.95
7. Design Variables
Use Antoine's existing wiffle tree and geometry parameters. Key ones likely include:
- Wiffle tree radial positions (R1, R2, R3)
- Wiffle tree angular offsets
- Rib thickness
- Back pocket geometry
- Support pad locations
Ask Antoine for the current parameter names and ranges.
Validation Checklist
Before running optimization, verify:
- FEA solves all 6 subcases (90, 20, 30, 40, 50, 60)
- OP2 contains displacement results for all subcases
- Subcase labels in OP2 are angle numbers (check with extractor)
- Extractor returns valid results (run standalone test first)
- R² ≈ 1.0 (confirms physics model holds)
Test command:
from optimization_engine.extractors.extract_zernike_trajectory import extract_zernike_trajectory
result = extract_zernike_trajectory('path/to/solution.op2')
print(f"R² = {result['linear_fit_r2']}")
print(f"Total RMS = {result['total_filtered_rms_nm']} nm")
print(f"Coma RMS = {result['coma_rms_nm']} nm")
Expected Outputs
After running the extractor, you should see:
total_filtered_rms_nm: ~4-10 nm (integrated across angles)coma_rms_nm: ~3-10 nmastigmatism_rms_nm: ~3-10 nmlinear_fit_r2: ~1.0
During optimization, track:
- How
total_filtered_rms_nmdecreases - Which modes (coma, astig, etc.) improve most
- Whether R² stays high (if it drops, something is wrong)
Key Files to Reference
| File | Purpose |
|---|---|
docs/physics/ZERNIKE_TRAJECTORY_METHOD.md |
Full method documentation |
docs/examples/trajectory_optimization_config.yaml |
Example config |
optimization_engine/extractors/extract_zernike_trajectory.py |
Extractor code |
2-Projects/P04-GigaBIT-M1/Technical-Analysis/Tensor_Project/TECH-SPEC-Zernike-Trajectory-Optimization.md |
Physics derivation + validation results |
Questions?
If anything is unclear, the tech spec in PKM has the full physics derivation and validation results. The extractor auto-detects angles from OP2 subcase labels, so as long as the FEA is set up correctly, it should "just work."
Good luck! 🚀
Handoff document by Mario (Clawdbot), 2026-01-29