209 lines
5.4 KiB
Markdown
209 lines
5.4 KiB
Markdown
|
|
# 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
|
||
|
|
|
||
|
|
1. ✅ **Extractor implemented:** `optimization_engine/extractors/extract_zernike_trajectory.py`
|
||
|
|
2. ✅ **Validated on M1 model:** R² = 1.0 (physics model confirmed)
|
||
|
|
3. ✅ **Documentation:** `docs/physics/ZERNIKE_TRAJECTORY_METHOD.md`
|
||
|
|
4. ✅ **Example config:** `docs/examples/trajectory_optimization_config.yaml`
|
||
|
|
|
||
|
|
**Pull latest from Gitea:**
|
||
|
|
```bash
|
||
|
|
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:
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
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):**
|
||
|
|
```yaml
|
||
|
|
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):**
|
||
|
|
```yaml
|
||
|
|
- 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):**
|
||
|
|
```yaml
|
||
|
|
optimizer:
|
||
|
|
type: tpe
|
||
|
|
config:
|
||
|
|
n_trials: 100
|
||
|
|
n_startup_trials: 15
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6. Constraints (Optional but Recommended)
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
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:**
|
||
|
|
```python
|
||
|
|
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 nm
|
||
|
|
- `astigmatism_rms_nm`: ~3-10 nm
|
||
|
|
- `linear_fit_r2`: ~1.0
|
||
|
|
|
||
|
|
During optimization, track:
|
||
|
|
- How `total_filtered_rms_nm` decreases
|
||
|
|
- 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*
|