info files added from claude
CI for csaxs_bec / test (push) Successful in 1m33s

This commit is contained in:
x01dc
2026-07-13 16:25:32 +02:00
parent 9a83a44674
commit 129ad05119
2 changed files with 1057 additions and 0 deletions
@@ -0,0 +1,450 @@
# BEC Beamline Experiment Control: System Overview
> **Erstellt:** April 2026
> **Zweck:** Referenzdokument für Claude (AI-Assistent) zur Orientierung im BEC-Ökosystem am cSAXS-Beamline (X12SA, PSI).
> **Nicht entwickelt von Nutzer:** Der Nutzer entwickelt *BEC-Begleit-Software* für cSAXS und die 3D-Ptychographie-Setups (LamNI, OMNY), nicht den BEC-Kern selbst.
---
## 1. Was ist BEC?
**BEC** steht für **Beamline and Experiment Control**. Es ist ein modulares, microservice-basiertes System zur Steuerung von Experimenten an Großforschungsanlagen (Synchrotrons, Neutronenquellen). Entwickelt am PSI (Paul Scherrer Institut), Schweiz.
- **Lizenz:** BSD-3-Clause
- **Sprache:** Python (>99%)
- **Python-Versionen:** 3.11, 3.12, 3.13
- **Aktuelle Version:** ~3.117.x (bec-Kern), ~3.5.x (bec_widgets), ~1.36.x (ophyd_devices)
- **Kommunikations-Backbone:** Redis (Pub/Sub + Streams)
- **Dokumentation:** https://bec.readthedocs.io / https://beamline-experiment-control.readthedocs.io
---
## 2. Architektur-Überblick
```
┌──────────────────────────────────────────────────────────────────┐
│ BEC Ecosystem │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ bec_ipython_ │ │ bec_widgets │ ← GUIs (PySide6) │
│ │ client (CLI) │ │ (Qt/PySide6) │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ └──────────┬───────────┘ │
│ │ bec_lib (gemeinsame Bibliothek) │
│ │ Redis Connector / Messages / Endpoints │
│ │ │
│ ┌──────────▼───────────────────────────┐ │
│ │ REDIS │ │
│ │ (Pub/Sub + Streams, single source │ │
│ │ of truth für alle Services) │ │
│ └──────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────▼──────────────────┐ │
│ │ bec_server │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ device_server │ │ ← ophyd / EPICS │
│ │ │ scan_server │ │ │
│ │ │ scan_bundler │ │ │
│ │ │ file_writer │ │ │
│ │ │ data_processing │ │ ← DAP Plugins │
│ │ │ scihub │ │ ← Logbook, Atlas │
│ │ └─────────────────────┘ │ │
│ └──────────┬──────────────────┘ │
│ │ │
│ ┌──────────▼──────────────────┐ │
│ │ Hardware / EPICS IOCs │ │
│ │ (Motoren, Detektoren, ...) │ │
│ └─────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Beamline-spezifische Plugins (z.B. csaxs_bec):
- Erweitern device_server, scan_server, file_writer, bec_widgets
- Laden über BEC Plugin-System (pyproject.toml entry points)
```
---
## 3. Kern-Repositories
Alle unter: https://gitea.psi.ch/bec (Mirrors von https://github.com/bec-project)
| Repository | Beschreibung | Wichtig für |
|---|---|---|
| **bec** | Haupt-Monorepo | Alles |
| **bec_widgets** | Qt/PySide6 GUI-Toolkit | GUI-Entwicklung |
| **ophyd_devices** | Geräteklassen (ophyd-Erweiterung) | Device-Entwicklung |
| **csaxs_bec** | cSAXS-spezifische Plugins | cSAXS / LamNI / OMNY |
---
## 4. Repository: `bec` (Monorepo)
**URL:** https://gitea.psi.ch/bec/bec
**GitHub:** https://github.com/bec-project/bec
**Struktur:**
```
bec/
├── bec_lib/ ← Gemeinsame Python-Bibliothek
│ └── bec_lib/
│ ├── client.py ← BECClient Hauptklasse
│ ├── device.py ← Device-Klassen (Wrapper um ophyd)
│ ├── devicemanager.py ← DeviceManager (dev.samx, etc.)
│ ├── endpoints.py ← Redis Message Endpoints (alle Topics)
│ ├── messages.py ← Message-Typen (Pydantic-ähnlich)
│ ├── redis_connector.py ← Redis-Verbindung (pub/sub, streams)
│ ├── connector.py ← Abstrakte Connector-Klasse
│ ├── scan_items.py ← Scan-Objekte
│ ├── queue_items.py ← Scan-Queue-Management
│ ├── callback_handler.py← Callback-System
│ ├── alarm_handler.py ← Alarm-Handling
│ ├── bec_service.py ← Basis-Klasse für alle BEC-Services
│ ├── bec_errors.py ← Fehlerklassen
│ ├── logger.py ← Logging-System
│ ├── file_utils.py ← Datei-Hilfsfunktionen
│ ├── live_scan_data.py ← Live-Daten während Scan
│ ├── dap_plugins.py ← Data Analysis Plugins
│ ├── dap_plugin_objects.py
│ ├── lmfit_serializer.py← lmfit-Integration (Kurvenanpassung)
│ ├── metadata_schema.py ← Scan-Metadata Schema
│ ├── plugin_helper.py ← Plugin-Hilfsfunktionen
│ ├── logbook_connector.py← Scilog/Logbook
│ ├── acl_login.py ← Zugangskontrolle
│ ├── bl_state_manager.py← Beamline State
│ ├── codecs.py ← Serialisierung (msgpack)
│ ├── numpy_encoder.py ← NumPy-Serialisierung
│ ├── configs/ ← Default-Konfigurationen
│ ├── procedures/ ← Scan-Prozeduren
│ └── utils/ ← Hilfsfunktionen
├── bec_server/ ← Server-Seite (alle Microservices)
│ └── bec_server/
│ ├── device_server/ ← Kommuniziert mit Hardware via ophyd/EPICS
│ ├── scan_server/ ← Führt Scans aus, verwaltet Queue
│ ├── scan_bundler/ ← Bündelt Scan-Daten (Device + Scan Events)
│ ├── file_writer/ ← Schreibt HDF5/NeXus-Dateien
│ ├── file_writer_plugins/← Plugin-System für Dateiformat
│ ├── data_processing/ ← Online-Datenanalyse (DAP)
│ ├── procedures/ ← Server-seitige Prozeduren
│ ├── scihub/ ← Anbindung externe Dienste (Atlas, Scilog)
│ └── bec_server_utils/ ← CLI-Argument-Parsing
├── bec_ipython_client/ ← IPython CLI Interface
│ └── bec_ipython_client/
│ ├── bec_startup.py ← Startup-Script (lädt beim `bec`-Command)
│ ├── main.py ← Einstiegspunkt
│ ├── bec_magics.py ← IPython Magic Commands (%bec, etc.)
│ ├── beamline_mixin.py ← Beamline-spezifische Mixins
│ ├── callbacks/ ← CLI-Callbacks (Progress, Printing)
│ ├── high_level_interfaces/ ← Höhere API (scans, dev, etc.)
│ └── plugins/ ← Plugin-Verzeichnis
├── pytest_bec_e2e/ ← End-to-End Tests
├── docs/ ← Sphinx-Dokumentation
├── bin/ ← Start-Scripts
└── bec_config_template.yaml ← Beispiel-Konfiguration
```
### Wichtige Konzepte in bec_lib
**Redis Endpoints** (`endpoints.py`): Alle Redis-Topics sind hier zentral definiert.
Beispiele:
- `MessageEndpoints.device_readback(device_name)` → live Gerätewert
- `MessageEndpoints.scan_segment` → Scan-Datenpunkte
- `MessageEndpoints.scan_status` → Scan-Status
**BECClient** (`client.py`): Haupt-Einstiegspunkt für alle Clients:
```python
from bec_lib.client import BECClient
bec = BECClient()
bec.start()
scans = bec.scans
dev = bec.device_manager.devices
```
---
## 5. Repository: `ophyd_devices`
**URL:** https://gitea.psi.ch/bec/ophyd_devices
**GitHub:** https://github.com/bec-project/ophyd_devices
**Beschreibung:** Erweiterung von [ophyd](https://blueskyproject.io/ophyd/) für Geräte, die nicht durch Standard-EPICS-ophyd abgedeckt sind.
```
ophyd_devices/
├── ophyd_devices/
│ ├── devices/ ← Konkrete Geräteklassen (EpicsMotor-Subklassen, etc.)
│ ├── interfaces/ ← Abstrakte Interface-Klassen (SimplePositioner, etc.)
│ ├── sim/ ← Simulierte Geräte für Tests/Demos
│ ├── configs/ ← Beispiel-Gerätekonfigurationen (YAML)
│ ├── utils/ ← Hilfsfunktionen (Static Device Tests, etc.)
│ └── tests/ ← Unit-Tests
└── tests/ ← Integrations-Tests
```
**Zentrale Konzepte:**
- Geräte erben von ophyd (`Device`, `EpicsMotor`, `EpicsSignal`, etc.)
- BEC-spezifische Erweiterungen: Callbacks für Redis, BEC-Signale
- `interfaces/` enthält abstrakte Klassen wie `SimplePositioner`
- Simulierte Geräte in `sim/` für Offline-Entwicklung
---
## 6. Repository: `bec_widgets`
**URL:** https://gitea.psi.ch/bec/bec_widgets
**GitHub:** https://github.com/bec-project/bec_widgets
**Framework:** PySide6 (Qt6)
```
bec_widgets/
├── bec_widgets/
│ ├── widgets/
│ │ ├── plots/ ← Waveform, MultiWaveform, Image/Heatmap
│ │ ├── control/ ← PositionerBox, TweakWidget, ScanControl
│ │ ├── containers/ ← BECDockArea (Haupt-Layout-Container)
│ │ ├── dap/ ← Data Analysis Plugin Widgets (lmfit Dialog)
│ │ ├── editors/ ← Code/Config-Editoren
│ │ ├── progress/ ← Scan-Fortschrittsanzeige
│ │ ├── services/ ← Service-Status-Widgets
│ │ ├── utility/ ← Diverse Hilfs-Widgets
│ │ └── games/ ← Easter Egg 🎮
│ ├── cli/ ← RPC-CLI Bindings (auto-generiert via bw-generate-cli)
│ ├── applications/ ← Fertige Anwendungen (BEC Launcher, Designer, Terminal)
│ ├── utils/ ← Plugin-Template-Generator, Hilfsfunktionen
│ ├── examples/ ← Beispiel-Widgets
│ └── assets/ ← Icons, Bilder
├── tests/
└── docs/
```
**Kern-Konzepte:**
- `BECWidget` (Basisklasse): Alle Widgets erben davon. Bietet BEC/Redis-Verbindung, RPC.
- `BECDispatcher`: Vermittelt Redis-Events an Qt-Slots.
- `USER_ACCESS` Liste: Definiert, welche Methoden über RPC erreichbar sind.
- `SafeSlot`: Thread-sicherer Qt-Slot Decorator.
- `BECDockArea`: Haupt-GUI-Container mit Drag-and-Drop-Docking.
**Widget erstellen (Minimalbeispiel):**
```python
from bec_widgets import BECWidget, SafeSlot
from bec_lib.endpoints import MessageEndpoints
class MyWidget(BECWidget, QWidget):
USER_ACCESS = ["my_method"]
def __init__(self, parent=None, **kwargs):
super().__init__(parent=parent, **kwargs)
self.bec_dispatcher.connect_slot(
self.on_data,
MessageEndpoints.device_readback("samx")
)
@SafeSlot(dict, dict)
def on_data(self, data, meta):
...
```
**CLI starten:** `bec` → öffnet IPython + BECDockArea GUI
**Designer:** `bec-designer` → Qt Designer mit BEC-Widgets
**RPC generieren:** `bw-generate-cli --target <plugin-repo>`
---
## 7. Repository: `csaxs_bec`
**URL:** https://gitea.psi.ch/bec/csaxs_bec
**Beschreibung:** cSAXS-spezifische Plugins und Konfigurationen für BEC (X12SA Beamline, PSI)
```
csaxs_bec/
├── csaxs_bec/
│ ├── devices/ ← cSAXS-Hardware-Geräteklassen
│ │ ├── epics/ ← Standard EPICS Geräte (MCS-Karte, etc.)
│ │ ├── ids_cameras/ ← IDS-Kameras (Alignment-Kameras)
│ │ ├── jungfraujoch/ ← JungFrauJoch (JFJ) Detektor-Integration
│ │ ├── npoint/ ← nPoint Piezo-Positionierer (Nano-Scans)
│ │ ├── omny/ ← OMNY Tomographie-Stage
│ │ ├── panda_box/ ← PandaBox Timing/Trigger-System
│ │ ├── pseudo_devices/ ← Pseudo-Geräte (berechnete Positionen)
│ │ ├── sls_devices/ ← SLS-spezifische Geräte (Synchrotron Light Source)
│ │ ├── smaract/ ← SmarAct Piezo-Positionierer
│ │ ├── tests_utils/ ← Test-Hilfsfunktionen (patch_dual_pvs)
│ │ └── device_list.md ← Dokumentation aller Geräte
│ │
│ ├── scans/ ← cSAXS-spezifische Scan-Plugins
│ │ ├── flomni_fermat_scan.py ← FlOMNI Fermat-Spiral Scan (Ptychographie)
│ │ ├── omny_fermat_scan.py ← OMNY Fermat-Spiral Scan
│ │ ├── LamNIFermatScan.py ← LamNI Fermat-Scan (3D Ptychographie!)
│ │ ├── jungfrau_joch_scan.py ← JFJ-spezifischer Scan
│ │ ├── sgalil_grid.py ← SGalil Grid-Scan (Galil-Controller)
│ │ ├── owis_grid.py ← OWIS Grid-Scan
│ │ ├── scan_plugin_template.py← Vorlage für neue Scan-Plugins
│ │ └── metadata_schema/ ← cSAXS Metadata-Schema
│ │
│ ├── bec_widgets/ ← cSAXS-spezifische GUI-Widgets
│ │ ├── widgets/
│ │ │ ├── xray_eye/ ← X-Ray Eye Widget (Kamera-Alignment-Tool)
│ │ │ └── client.py ← RPC-Client für cSAXS-Widgets
│ │ └── auto_updates/ ← Automatische GUI-Updates
│ │
│ ├── bec_ipython_client/ ← cSAXS CLI-Erweiterungen
│ │ └── ... ← Web-Generator, Auth-Integration
│ │
│ ├── device_configs/ ← YAML-Gerätekonfigurationen
│ │ └── ... ← z.B. bec_device_config_sastt.yaml
│ │
│ ├── file_writer/ ← cSAXS-spezifischer File Writer Plugin
│ ├── dap_services/ ← Online Datenanalyse (DAP) Services
│ ├── macros/ ← BEC-Makros
│ ├── services/ ← Zusatz-Services
│ └── deployments/ ← Deployment-Konfigurationen
├── bin/ ← Start-Scripts
├── docs/ ← Dokumentation
└── tests/ ← Tests
```
### Hardware am cSAXS (X12SA)
| Gerät | Klasse/Modul | Typ |
|---|---|---|
| Eiger | EPICS IOC | Röntgen-Flächendetektor |
| Pilatus 300K | EPICS IOC | Röntgen-Flächendetektor |
| FalconX1 | EPICS IOC | Fluoreszenz-Detektor |
| JungFrauJoch (JFJ) | `devices/jungfraujoch/` | Röntgen-Detektor (High-rate) |
| OMNY | `devices/omny/` | Tomographie-Drehtisch |
| nPoint | `devices/npoint/` | Piezo-Positionierer (Nano) |
| SmarAct | `devices/smaract/` | Piezo-Positionierer |
| PandaBox | `devices/panda_box/` | Timing/Trigger-System |
| MCS-Karte | `devices/epics/` | Multi-Channel Scaler |
| IDS-Kameras | `devices/ids_cameras/` | Sichtbare-Licht-Kameras |
| SGalil | EPICS/Config | Galil-Motorcontroller |
| OWIS | Config | Motorcontroller |
| Delay Generator (DDG) | EPICS IOC | Pulsgenerator (Timing) |
### Scans am cSAXS
| Scan | Datei | Verwendung |
|---|---|---|
| `sgalil_grid` | `sgalil_grid.py` | Standard-Raster-Scan (Galil-Controller) |
| `omny_fermat_scan` | `omny_fermat_scan.py` | OMNY Fermat-Spiral (Ptychographie) |
| `flomni_fermat_scan` | `flomni_fermat_scan.py` | FlOMNI Fermat-Spiral |
| `LamNIFermatScan` | `LamNIFermatScan.py` | **3D Ptychographie (LamNI)** |
| `jungfrau_joch_scan` | `jungfrau_joch_scan.py` | JFJ-Burst-Akquisition |
| `owis_grid` | `owis_grid.py` | OWIS-Raster-Scan |
---
## 8. Beamline-Setup: cSAXS (X12SA)
**Beamline:** X12SA, Paul Scherrer Institut (PSI), Schweiz
**Synchrotron:** SLS (Swiss Light Source)
### 3D Ptychographie / LamNI
**LamNI** = *Laminar Nano-Imaging* das 3D Ptychographie-Setup am cSAXS.
Relevante Komponenten:
- **Scan:** `LamNIFermatScan` (Fermat-Spiral, optimiert für Ptychographie)
- **Positionierung:** nPoint Piezo-Stages (Nanometer-Präzision) + übergeordnete Motoren
- **Detektor:** Eiger oder ähnlich (kohärentes Streumuster)
- **Timing:** PandaBox oder Delay-Generator
### OMNY
OMNY = Tomographie-System mit Drehtisch.
- **Scan:** `omny_fermat_scan`
- **Gerät:** `devices/omny/`
- Verwendet einen dedizierten "Flyer" für kontinuierliche Akquisition
### Startup am cSAXS
```bash
# BEC-Server starten (auf pc15543)
cd ~/Data10/software
source bec_venv/bin/activate
bec-server start
tmux attach -t bec
# BEC-Client starten
bec
# Gerätekonfiguration laden
bec.config.update_session_with_file('~/Data10/software/csaxs-bec/bec_plugins/configs/bec_device_config_sastt.yaml')
```
---
## 9. BEC Plugin-System
BEC nutzt Python Entry Points für Plugins. Ein Plugin-Paket (z.B. `csaxs_bec`) registriert seine Komponenten in `pyproject.toml`:
```toml
[project.entry-points."bec.plugins"]
csaxs_bec = "csaxs_bec"
[project.entry-points."bec.scan_plugins"]
csaxs_scans = "csaxs_bec.scans"
[project.entry-points."bec.file_writer_plugins"]
csaxs_writer = "csaxs_bec.file_writer"
```
BEC lädt automatisch alle registrierten Plugins beim Start.
---
## 10. Kommunikation & Datenfluss
```
Hardware → EPICS IOC → ophyd (device_server) → Redis
Client (bec_lib) ← Redis ← scan_bundler ← scan_server
file_writer → HDF5/NeXus Dateien
data_processing (DAP) → Online-Analyse
```
**Wichtige Redis Message-Typen** (in `bec_lib/messages.py`):
- `DeviceMessage` Gerätewerte
- `ScanMessage` Scan-Informationen
- `BECStatus` Service-Status
- `AlarmMessage` Alarme/Fehler
- `LogMessage` Log-Einträge
- `ScilogMessage` Logbuch-Einträge
---
## 11. Entwicklungs-Workflow
### Code-Standards
- **Formatter:** Black (`--line-length=100 --skip-magic-trailing-comma`)
- **Import-Sortierung:** isort (`--profile=black`)
- **Linter:** Pylint
- **Tests:** pytest
- **Commit-Format:** Conventional Commits (`feat:`, `fix:`, `refactor:`, etc.)
### Typisches Widget-Entwicklungs-Muster (csaxs_bec)
1. Widget-Klasse in `csaxs_bec/bec_widgets/widgets/<name>/` erstellen
2. Von `BECWidget` + Qt-Widget erben
3. `USER_ACCESS` für RPC definieren
4. Auf Redis-Endpoints subscriben via `bec_dispatcher.connect_slot()`
5. RPC-Client generieren: `bw-generate-cli --target csaxs_bec`
6. Qt-Designer-Plugin wird automatisch registriert
### Typisches Scan-Entwicklungs-Muster
1. Scan-Klasse in `csaxs_bec/scans/` erstellen
2. Von BEC-Basis-Scan-Klasse erben
3. In `pyproject.toml` registrieren
4. Zugriff im Client: `scans.mein_scan(...)`
---
## 12. Nützliche Links
| Ressource | URL |
|---|---|
| BEC Gitea | https://gitea.psi.ch/bec |
| BEC GitHub | https://github.com/bec-project |
| BEC Docs | https://bec.readthedocs.io |
| BEC Widgets Docs | https://bec-widgets.readthedocs.io |
| ophyd Docs | https://blueskyproject.io/ophyd/ |
| cSAXS BEC Repo | https://gitea.psi.ch/bec/csaxs_bec |
---
*Dieses Dokument sollte dem Projekt hinzugefügt werden und dient als primäre Referenz für Claude in zukünftigen Gesprächen.*
@@ -0,0 +1,607 @@
# cSAXS Setups: LamNI, OMNY, FlOMNI Vollständige technische Referenz
> **Quellen:** Quellcode `csaxs_bec` + vier peer-reviewed Publikationen:
> - Holler et al., *J. Synchrotron Rad.* **27**, 730736 (2020) → LamNI
> - Holler et al., *Rev. Sci. Instrum.* **89**, 043706 (2018) → OMNY
> - Holler et al., *Rev. Sci. Instrum.* **83**, 073703 (2012) → FlOMNI (RT-Vorgänger)
> - Holler & Raabe, *Opt. Eng.* **54**, 054101 (2015) → Tracking-Interferometer
---
## ❗ WICHTIGE KORREKTUR: Was ist LamNI wirklich?
**LamNI = Laminographic Nano-Imaging** (NICHT "Laminar Nano-Imaging"!)
LamNI ist ein Instrument für **ptychographische Röntgen-Laminographie** (PyXL).
Laminographie unterscheidet sich grundlegend von Tomographie:
| | Tomographie (OMNY) | Laminographie (LamNI) |
|---|---|---|
| Rotationsachse | ⊥ zum Röntgenstrahl (90°) | Geneigt zum Strahl (≠ 90°) |
| Probenform ideal | Zylindrisch (Pfeiler/Pillar) | Planar (flache Chips, Schichten) |
| FOV-Winkelbereich | 0°–180° (vollständig) | 0°–360° (voller Umlauf nötig) |
| Fehlende Information | Keine (vollständig) | Missing cone (statt Wedge) |
| Präparation | Destruktiv (FIB-Pillar nötig) | Minimal (großflächige Proben!) |
| Anwendung bei PSI | OMNY | LamNI |
**Laminographiewinkel bei LamNI:** 61° (zwischen Rotationsachse und Röntgenstrahl)
Erzeugt durch: Erst 15° Kippen um x-Achse, dann 60° um y-Achse.
**Das erklärt den Code direkt:**
```python
MOVEMENT_SCALE_X = np.sin(np.radians(15)) * np.cos(np.radians(30))
MOVEMENT_SCALE_Y = np.cos(np.radians(15))
```
Die 15° entsprechen der Stage-Verkippung in x. Die Koordinatentransformation ist notwendig, weil der Piezo-Scanner in der geneigten Stage-Ebene bewegt, die Interferometer aber im Laborrahmen messen.
---
## 1. LamNI Laminographic Nano-Imaging
### Physikalisches Prinzip
Kohärente Röntgenstrahlung (~610 keV) wird durch eine Fresnel-Zonenplatte (FZP) fokussiert. Die Probe wird in einem Fermat-Spiralmuster abgetastet (Ptychographie). Für die 3D-Information wird die Probe um die geneigte Achse (61° zur Strahlrichtung) rotiert. Das erlaubt die Abbildung **flacher, großflächiger Proben** (ICs, Schichten) ohne destruktive Pillar-Präparation.
**Anwendungen:**
- Integrierte Schaltkreise (IC, 16-nm-Technologie-Knoten demonstriert: 18.9 nm Auflösung)
- Magnetische Strukturen (zeitaufgelöste Laminographie, 50 nm / 70 ps)
- Großflächige Materialien in 3D
### Hardware-Komponenten (aus Paper 2020)
```
LamNI Mechanik (110 × 130 cm Grundplatte, 1 Tonne Gewicht)
├── Röntgenoptik (upstream)
│ ├── FZP auf xyz-Stages (Steinmeyer Mechatronik, Schrittmotoren)
│ ├── CS (Central Stop) auf xy-Stages (SmarAct GmbH)
│ ├── OSA (Order Sorting Aperture) auf xyz-Stages (SmarAct GmbH)
│ ├── Flachspiegel (x und y) für Interferometer am FZP-Halter
│ └── Helium-Flugrohr (reduziert Luftstreuung)
└── Probenstage (gestapelt)
├── Grobe Translationsstages (Steinmeyer Mechatronik, Schrittmotoren)
│ └── Für Stitching und Region-of-Interest-Auswahl
├── Großer Rotationstisch (air-bearing, 365°, Radius 175 mm)
│ ├── Renishaw Tonic Dual-Encoder-System
│ ├── Luftlager → nach Rotation abgelassen → mechanisch geklemmt → steifer
│ └── Schrittmotor-Antrieb (Steinmeyer Mechatronik)
├── Piezo-Scanner (Npoint NPXY100-216)
│ ├── 2 Translationsachsen (x, y in Stage-Ebene)
│ ├── 100 µm Stellbereich je Achse
│ ├── Interne kapazitive Sensoren (nur für Vorpositionierung)
│ └── Closed-loop zum exteroceptiven Interferometer (Hauptregelung!)
└── Anti-Rotations-Stage (Kugellager, PASSIV kein Antrieb!)
├── Trägt die Interferometer-Spiegel
├── Dreht sich NICHT mit dem Probentisch (hält Spiegel senkrecht)
├── Passiver Antrieb: Hebelarm + zwei Hardstops am Rotationstisch
├── Pneumatische Bremse: Fixiert Spiegel während Scan
└── Kapazitive Sensoren (A: Abstand zu Hardstops, B: Winkelmotion)
```
### Device-Namen in BEC (LamNI)
| BEC-Device | Hardware | Einheit | Anmerkung |
|---|---|---|---|
| `rtx` | RT-Controller X (Piezo-Scanner Npoint X-Achse) | µm | Interferometer-geregelt |
| `rty` | RT-Controller Y (Piezo-Scanner Npoint Y-Achse) | µm | Interferometer-geregelt |
| `lsamx` | Koarse-Motor X (Steinmeyer) | mm | Read-only bei aktivem Feedback |
| `lsamy` | Koarse-Motor Y (Steinmeyer) | mm | Read-only bei aktivem Feedback |
| `lsamrot` | Großer Rotationstisch (air-bearing) | Grad | Laminographie-Winkel |
| `loptx` | Optik-Motor X | mm | FZP/OSA-Ausrichtung |
| `lopty` | Optik-Motor Y | mm | |
| `loptz` | Optik-Motor Z | mm | |
### Interferometer-System (LamNI)
- **Typ:** Doppeldurchgang-Flachspiegel (KEIN Tracking-Interferometer!)
Grund: 12 mm × 12 mm Scanbereich zu groß für Tracking mit Kugelspiegeln
- **Laser:** Zygo Inc., 6 mm Strahldurchmesser
- **Gemessen:** Relative Position FZP ↔ Probe (x und y, exteroceptiv)
- **Anti-Rotations-Stage** hält Spiegel senkrecht zum Interferometerstrahl während Rotation
- **Positionsstabilität:** 1.1 nm Standardabweichung (x und y)
- **Positioniergenauigkeit:** 4.4 nm (H), 4.1 nm (V) std (ptychographisch verifiziert)
- **Schrittantwort:** < 40 ms für 1.5 µm Schritt
### LamNI Geometrie im Detail
```
Koordinatensystem (Labor):
z = Röntgenstrahl-Richtung
x = horizontal
y = vertikal (zeigt nach oben)
Stage-Verkippung:
1. 15° Kippung um x-Achse
2. 60° Kippung um y-Achse
→ Laminographie-Winkel (Strahl ↔ Rotationsachse) = 61°
Piezo-Scan-Ebene:
= Probenebene (geneigt gegenüber Labor-Koordinaten)
Interferometer-Messung:
= In Laborkoordinaten x und y
→ Koordinatentransformation notwendig:
(Code: lamni_to_stage_coordinates / lamni_from_stage_coordinates)
Rotation im Code (Winkelkorrektur):
alpha = (angle - 300 + 30.538) / 180 * pi
→ Die 300° und 30.538° sind mechanische Offsets des Setups
```
### Anti-Rotations-Mechanismus (LamNI-spezifisch)
```
Problem: Interferometer-Spiegel müssen senkrecht zum Strahl bleiben,
aber Probe dreht sich mit dem Rotationstisch!
Lösung: Anti-Rotations-Stage auf dem Piezo-Scanner
1. Großer Rotationstisch dreht (z.B. 45°)
2. Hebelarm der kleinen Stage berührt Hardstop an der Basis des großen Tisches
3. Kleine Stage dreht sich passiv um -45°
4. Ergebnis: Spiegel bleiben in Laborkoordinaten ausgerichtet ✓
Sicherheit:
- Kapazitive Sensoren (A): Abstand Hebel ↔ Hardstop überwacht
- Kapazitive Sensoren (B): Winkelmotion der kleinen Stage
- Pneumatische Bremse: Fixiert Spiegel während Scan
- Auto-Entklemmen wenn Hebel zu nah an Hardstop (Sicherheitsmechanismus)
Prozedur bei Rotationswechsel:
1. Piezo auf interne kapazitive Sensoren zentrieren
2. Interferometer-Feedback ausschalten
3. Bremse der kleinen Stage lösen
4. Luftlager einschalten
5. Großen Tisch zum Zielwinkel drehen (Encoder-Feedback)
6. Kleine Stage klemmen
7. Feinausrichtung der kleinen Stage (kap. Sensoren A → Servo-Regelung)
8. Luftlager ausschalten (erhöht Steifigkeit)
9. Letzten Encoder-Wert speichern (tatsächlicher Winkel für Rekonstruktion)
```
### Scan-Aufruf und Parameter (LamNI)
```python
# Standard LamNI Fermat-Scan
scans.lamni_fermat_scan(
fov_size=[20], # FOV in Piezo-Ebene [µm], max ~80 µm
# [x] = quadratisch, [x,y] = rechteckig
step=0.5, # Schrittweite [µm]
exp_time=0.1, # Belichtungszeit [s]
angle=0, # Laminographie-Rotationswinkel [Grad]
center_x=0.02, # Scan-Zentrum X bei 0° [mm] WIRD rotiert!
center_y=0, # Scan-Zentrum Y [mm]
shift_x=0, # Zusatzshift X [mm] wird NICHT rotiert
shift_y=0, # Zusatzshift Y [mm]
stitch_x=0, # Stitch-Versatz X [µm]
stitch_y=0, # Stitch-Versatz Y [µm]
fov_circular=0, # Kreisförmiges FOV [µm] (zusätzliches Cropping)
stitch_overlap=1, # Stitch-Überlapp [µm]
scan_type="fly", # "fly" (HW-getriggert) oder "step"
frames_per_trigger=1,
)
# Zu neuem Scan-Zentrum fahren (rotations-kompensiert):
scans.lamni_move_to_scan_center(shift_x_mm, shift_y_mm, angle_deg)
```
### LamNI Leistungsdaten
| Parameter | Wert |
|---|---|
| Scan-Bereich | 12 mm × 12 mm (über Stitching) |
| Piezo-Bereich | 100 µm × 100 µm (Npoint NPXY100-216) |
| Positionsstabilität | 1.1 nm std |
| Schrittantwort | < 40 ms für 1.5 µm |
| Positioniergenauigkeit | 4 nm std (ptychographisch) |
| Beste 3D-Auflösung | 18.9 nm (IC 16-nm-Technologie) |
| Gewicht | 1 Tonne |
| Grundplatte | 110 × 130 cm |
---
## 2. OMNY tOMography Nano crYo Stage
### Physikalisches Prinzip
OMNY = kryogene Ptychographie-Tomographie. Die Rotationsachse ist senkrecht zum Röntgenstrahl (klassische Tomographie, 90°). Kryogene Bedingungen (90 K mit LN₂, 10 K mit LHe) schützen strahlungsempfindliche Proben.
**Betrieb bei cSAXS seit:** Juni 2015
**Vakuum:** Ultra-Hochvakuum (10⁻⁷–10⁻⁸ mbar)
**Probengeometrie:** Zylindrische Pfeiler (OMNY Pins)
### Hardware-Komponenten (aus Paper 2018)
```
OMNY Mechanik (Vakuumkammer Ø 110 cm, 4 Tonnen Gewicht)
Mineral-Cast-Block: 110 × 110 × 52 cm³
├── Röntgenoptik
│ ├── FZP auf 2D Piezo-Stage (nPoint, Inc., NPXY100D)
│ │ └── Controller: NPoint LC.403
│ ├── CS (Central Stop) auf xy-Stage (SmarAct SLC-2430-S-UHV)
│ └── OSA auf xyz-Stage; Cryo 2 gekühlt (90 K)
│ └── Spiegel-Mounts: SmarAct STT-25.4-UHV-TI (motorisiert)
├── Probenstage
│ ├── 4 Schrittmotor-Stages (xyz + Rotation um y)
│ │ ├── Linear: ±5 mm Range (Steinmeyer Mechatronik, Dresden)
│ │ ├── Rotation: 365°, Renishaw Tonic UHV Encoder
│ │ └── Controller: 3× Galil DMC-4080-D4140
│ ├── Delta-Scanner (Tripod-Geometrie, PSI-Eigenentwicklung, Maag et al.)
│ │ ├── 3 translatorische DOF, 450 µm Gesamtbereich
│ │ ├── Schrittantwort: < 30 ms für ~2 µm Schritte
│ │ ├── Lokale Metrologie: attocube Faserinterferometer (nanometrisch!)
│ │ ├── Piezo aufgeteilt in 4 unabhängige Stapel:
│ │ │ ├── High-Current Stapel: VF-500 Verstärker (1A) schnelle Bewegung
│ │ │ └── Low-Noise Stapel: SVR-150 Feinregelung (< 10 nm Rauschen)
│ │ └── Rotationsmatrix-Korrektur (Delta-Geometrie ≠ xyz des Labors)
│ └── Referenzspiegel / Probenhalter (Al, diamantgedreht, Au-beschichtet)
│ ├── LT Ultra GmbH (Herstellung)
│ ├── Vertikal: Flachfläche für Doppelpass-Interferometer
│ ├── Horizontal: Kugelform für Tracking-Interferometer
│ ├── Oberflächenfehler < 300 nm, Rauigkeit ~1 nm
│ └── Sample direkt montiert (minimiert Dead-Path!)
├── Kryosystem
│ ├── Cryo 1: Helitran LT3B (LN₂ oder LHe, offener Kreislauf, leise!)
│ │ └── O₂-freies Kupfergeflecht (514 mm) → Referenzspiegel
│ │ └── 4 × 16 mm² + 10 × 23 mm² (gestuft für Kraftreduktion)
│ ├── Cryo 2: LN₂-Rohrsystem → OSA (90K), Greifer, Parkstation, Therm. Schirm (108K)
│ │ └── Thermischer Schirm: SmarAct SLC-1750-S-UHV (kann weggefahren werden)
│ └── Aktive Temperaturregelung: Pt100 (Heraeus) + Heizwicklungen (Nichrom)
│ └── Stabilität bei LN₂: 90.000 K ± 3.3 mK (über Tage!)
├── Interferometer-System (Zygo Inc.)
│ ├── Laser: Modell 7714, 3 mm Strahldurchmesser
│ ├── Karten: Modell 4004 + 2400 (VME-Bus)
│ ├── VME64-to-PCI Adapter: Abaco Systems Modell 810
│ ├── 5 gemessene Größen:
│ │ ├── xy: Probe ↔ OSA (Tracking-IF für x, Flach für y)
│ │ ├── xy: OSA ↔ FZP (Doppeldurchgang-Flachspiegel)
│ │ └── Rotationswinkel um z des Probentisches
│ └── Tracking-Interferometer-Stage:
│ ├── y-Piezo: Dynamic Structures ZSA-400-PSI (400 µm, 200 Hz)
│ ├── z-Stepper + z-Piezo (50 µm): folgt Kugelspiegel-Wobble
│ └── Bremse: Piezoelektrisch (erhöht Steifigkeit der y-Stage)
├── Elektronik (National Instruments)
│ ├── NI 6259: Analog In/Out (2 Kanäle)
│ ├── NI 6733: Analog Out (8 Kanäle, Delta-Scanner + FZP)
│ └── NI 6602: Counter/Encoder (attocube-Quadratur-Encoder)
└── Load-Lock (Leica VCT100-basiert, modifiziert)
├── Turbomolekularpumpe (nur Befüllung/Transfer)
├── Bis 6 OMNY Pins pro Shuttle
└── Probengreifer für kryogenen Transfer
```
### OMNY Real-Time-Kontrollsystem (Fig. 7 im Paper)
```
Host-PC: Ubuntu Linux + RTAI 4.0 (Echtzeit-Kernel)
Schleifenfrequenz: 2.5 kHz
Frühere Kontrolle: SPEC (Certified Scientific Software) → jetzt: BEC!
Vollständiger Signalfluss:
┌─────────────────────────────────────────────────────────────┐
│ 2.5 kHz Loop │
│ │
│ Zygo-IF ──→ Slew-Rate-Limiter ──→ PID Sample xy │
│ │ │ │ │
│ │ Trajektorie-Gen. Rotationsmatrix │
│ │ │ │
│ │ PID Delta xy ──→ VF-500 │
│ │ │ SVR-150 │
│ Attocube ──→ Delta PID ──→ Range Extension │
│ │ │
│ Zygo FZP ──→ PID FZP xy ──→ NPoint LC.403 │
│ │
│ PSD Tracking ──→ PID Tracking yz ──→ ZSA-400-PSI Piezo │
│ │
│ Position-Sampler: Mean + Std jeder Achse während Belichtung│
└─────────────────────────────────────────────────────────────┘
Ethernet → SPEC/BEC (asynchron, nicht Echtzeit)
EPICS soft-IOC: Probenpositionen, Temperaturen, Vakuum-Status
```
### OMNY Mikroskop (X-Ray Eye)
Das interne Mikroskop (X-Ray Eye) hat 3 Modi:
1. **Weitwinkel** (Übersicht): Edmund Optics Objektiv + IDS UI-524xCP-C
2. **Röntgen-Ast**: Szintillator (LuAG:Ce, 0.1 mm) → Mitutoyo 20x → IDS UI-548xCP-M
- Optische Auflösung: 1 µm an der Szintillatorebene
3. **Sichtbar-Ast**: Leica Plan APO + Leica Z16 APO → IDS UI-548xCP-M
- Auflösung: 2.5 µm bei 400 nm, 66.4 mm vor Szintillator
Das X-Ray Eye ist die Basis des **`xray_eye`** BEC-Widgets in `csaxs_bec/bec_widgets/widgets/xray_eye/`!
### Device-Namen in BEC (OMNY)
| BEC-Device | Hardware | Beschreibung |
|---|---|---|
| `rtx` | Delta-Scanner X / RT-Controller | Interferometer-geregelt, Flyer-Start |
| `rty` | Delta-Scanner Y | |
| `rtz` | Delta-Scanner Z | Z-Richtung (Defokussierung) |
| `osamroy` | Rotationstisch | Tomographie-Winkel [Grad], 365° |
| `osamx` | Koarse-Motor X | Proben-Grobpositionierung |
| `rt_omny` | Sync-Flyer-Device | Überwacht Scan-Fortschritt |
### OMNY Alignment-Prozedur (aus Paper)
1. **Grob-Alignment**: X-Ray Eye Kamera + GUI (früher LabView, jetzt BEC)
- 5 Rotationswinkel gleichmäßig verteilt von 0° bis 180°
2. **Fein-Alignment**: 5 Ptychographie-Scans, sinusförmige Kurvenanpassung
3. **Affine-Korrektur**: Einmalig pro Run (Flipping-Experiment + FSC-Optimierung)
### OMNY Leistungsdaten
| Parameter | Wert |
|---|---|
| Probe-Stabilität | < 10 nm std (in-position während Belichtung) |
| Positioniergenauigkeit | 8.1 nm (H), 4.7 nm (V) std residues |
| Beste 2D-Auflösung | 8.5 nm (FRC, 1-bit Threshold) |
| Beste 3D-Auflösung (IC) | 14.6 nm (Nature 2017) |
| Beste 3D-Auflösung (biologisch, hochstreuend) | 27 nm (Käferflügelschuppe) |
| Biologisch schwach streuend | 111 nm (Chlamydomonas in OMNY, LN₂) |
| Probengröße max | ~50.000 µm³ Volumen |
| Röntgenenergie | 6.2 keV typisch |
| Detektor-Abstand | 7.33 m (Pilatus 2M) |
| Temperaturstabilität | 90.000 K ± 3.3 mK (über Tage) |
| Experimentlaufzeit | 56 Wochen kryogen (ohne Aufwärmen) |
---
## 3. FlOMNI Fly-OMNY (Raumtemperatur, Fly-Scan)
### Was ist FlOMNI?
**FlOMNI** ist der **Raumtemperatur**-Nachfolger des ursprünglichen RT-Instruments (Holler 2012). Es ist als **Async Fly-Scan** (`AsyncFlyScanBase`) konzipiert: die Probe bewegt sich kontinuierlich, während die Detektoren laufend aufnehmen. Das 2012er Paper beschreibt den direkten Vorgänger.
**Grundprinzip des Closed-Loop-Schemas (aus 2012er Paper):**
```
1. Probe zu Zielposition bewegen (nur interne kapazitive Sensoren)
2. Interferometer-Feedback an FZP-Piezo EINSCHALTEN
3. Belichtung: FZP kompensiert verbleibende Drift (< 50 nm Amplitude)
4. Interferometer-Mittelwert → Input für Ptychographie-Rekonstruktion
5. Interferometer-Feedback AUSSCHALTEN, FZP-Piezo zurückzentrieren
6. Nächste Position
```
Bei FlOMNI ist dies für kontinuierliche Bewegung optimiert (Fly-Scan).
### FlOMNI Besonderheiten
| Merkmal | Wert/Beschreibung |
|---|---|
| Betrieb | Raumtemperatur, Atmosphäre |
| Scan-Modus | Async Fly-Scan |
| BEC-Basisklasse | `AsyncFlyScanBase` |
| Tracker | **Laser-Tracker** (aktive Strahlverfolgung) |
| Trigger | DDG1 (Delay-Generator 1), `EXT_RISING_EDGE` |
| Cleanup | DDG1 zurück auf `SINGLE_SHOT` nach Scan |
| Scan-Umkehr | Jeder 2. Scan reversed (Redis global var) |
| FOV X max | 200 µm |
| FOV Y max | 100 µm |
| Z-Shift max | ±100 µm |
| Probenmagazin | `flomni_sample_storage` automatischer Probenwechsel! |
| Rotation | `fsamroy` (FlOMNI Rotationsmotor) |
| Flyer | `rt_positions` (AsyncFlyScanBase Monitor) |
| Temp-Monitoring | `flomni_temp_and_humidity.py` |
### Laser-Tracker (FlOMNI-spezifisch)
Im Gegensatz zu OMNY (klassisches Tracking-Interferometer) hat FlOMNI einen Laser-Tracker:
```python
# Im Scan-Code (flomni_fermat_scan.py):
yield from self.stubs.send_rpc_and_wait("rtx", "controller.laser_tracker_on")
tracker_signal = yield from self.stubs.send_rpc_and_wait(
"rtx", "controller.laser_tracker_check_signalstrength"
)
# Ergebnis: "ok", "low", oder "toolow"
if tracker_signal == "low":
# Alarm (WARNING), Scan kann weiterlaufen, Realignment empfohlen
elif tracker_signal == "toolow":
raise ScanAbortion("Laser-Tracker-Signal zu schwach Realignment nötig!")
# Nach Positionierung zum Scan-Zentrum:
yield from self.stubs.send_rpc_and_wait(
"rtx", "controller.move_samx_to_scan_region", self.cenx
)
```
### Device-Namen in BEC (FlOMNI)
| BEC-Device | Beschreibung |
|---|---|
| `rtx` | RT-Controller X + Laser-Tracker-Interface |
| `rty` | RT-Controller Y |
| `rtz` | RT-Controller Z (Defokussierung) |
| `fsamroy` | FlOMNI Rotationsmotor [Grad] |
| `ddg1` | Delay-Generator 1 (Trigger, EPICS) |
| `rt_positions` | Async-Flyer-Device |
---
## 4. Tracking-Interferometer Gemeinsame Schlüsseltechnologie
Das **Error-Motion-Compensating Tracking Interferometer** (Holler & Raabe, Opt. Eng. 2015, Patent WO 2012079875 A1) ist Grundlage für OMNY (und den RT-Vorgänger/FlOMNI):
### Das Problem bei rotierenden Proben
Bei Standard-Interferometern mit Kugelspiegel muss der Kugelspiegel präzise auf der Rotationsachse zentriert sein. Das ist in der Praxis nicht möglich → Kugelspiegel wackelt → Strahl trifft nicht mehr auf Kugelmitte → Signal verloren.
**Lösung 1 (einfach):** Interferometer auf x/y-Stage, PSD misst Strahlposition → Tracking
**Problem:** Tracking-Stage selbst hat Fehlermotion (Kugeellager: ~200 µrad Winkelfehler → ~3 µm Messfehler)
### Die optische Kompensation (Holler & Raabe 2015)
```
Aufbau (vier polarisierende Strahlteiler PBS1-PBS4, zwei externe Referenzspiegel R1, R2):
Referenzstrahl: f1,f2 → PBS1 → R1 → PBS1 → PBS2 → R2 → PBS2 → HWP → PBS4
Messstrahl: f1,f2 → PBS1 → PBS3 → Kugelspiegel → PBS3 → R2 → PBS4
Optische Wege:
Referenz: 2·(a + b) [a = PBS1 zu R1, b = PBS2 zu R2]
Messung: 2·(c + d) [c = PBS1 zu Sphäre, d = PBS3 zu R2]
OPD = 2·(a+b) - 2·(c+d)
Wenn Tracking-Stage sich um Δ bewegt (Translation):
a,c kürzen sich um Δ; b,d verlängern sich um Δ → OPD unverändert ✓
Wenn Tracking-Stage sich dreht (Rotation um Zentrum):
a,d kürzen sich; b,c verlängern sich → OPD unverändert ✓
R1 sitzt bei FZP-Position → direkte Differenzmessung Probe ↔ FZP!
```
**PSD misst Kugelposition in x/y:**
→ Closed-Loop zum Tracking → Kugel muss NICHT zentriert sein auf Rotationsachse!
**Ergebnis:**
- Ohne Kompensation: ~3 µm Restfehler (Kugeellager-Winkelfehler)
- Mit Kompensation: ~15 nm Restfehler (Faktor 200 besser!)
- In OMNY verwendet: Positionsstabilität < 10 nm std
### Warum LamNI kein Tracking-Interferometer braucht
Der LamNI-Scan ist 12 mm × 12 mm groß. Das überschreitet die praktikable Reichweite des Tracking-Systems mit Kugelspiegeln (begrenzt durch Tiefenschärfe des fokussierten Laserstrahls). Daher: Flachspiegel + Anti-Rotations-Stage als alternative Lösung.
---
## 5. nPoint Piezo-Controller Zwei verschiedene Rollen!
| | Bei OMNY | Bei LamNI |
|---|---|---|
| **Modell** | NPXY100D | NPXY100-216 |
| **Steuert** | **FZP-Position** (Röntgenoptik!) | **Probe** (Piezo-Scanner) |
| **Controller** | NPoint LC.403 | im RT-Controller integriert |
| **Bereich** | klein (Optik-Stabilisierung) | 100 µm × 100 µm |
| **Zweck** | FZP in closed-loop zur Interferometermessung | Proben-Scanning für Ptychographie |
**BEC-Driver:** `csaxs_bec/devices/npoint/npoint.py`
- Binary-Protokoll (LC.400/LC.403 Controller)
- `0xA0 [addr] 0x55` = Lesen; `0xA2 [addr] [data] 0x55` = Schreiben
- Positionsbereich: 0100% → intern 01048574 Integerwert
- 3 Achsen pro Controller
---
## 6. RT-Controller (LamNI-spezifisch) Socket-Protokoll
Der `RtLamniController` kommuniziert über TCP/IP Socket (ASCII-Kommandos):
| Kommando | Bedeutung |
|---|---|
| `J0` | Interferometer-Feedback deaktivieren |
| `J4` | Aktuelle Interferometerposition lesen (x, y, ...) |
| `J5` | Feedback aktivieren (ohne Reset der Zielposition) |
| `J6` | Feedback + Winkelinterferometer-Reset deaktivieren |
| `J2` | Feedback-Status + Interferometer-Signalstärke (SSI 0, SSI 1) |
| `J3` | SSI-Mittelung triggern (vor J2 aufrufen!) |
| `J7` | Winkel-Interferometer: Status, Position, Signalstärke |
| `sc` | Scan stoppen + Trajektorie löschen |
| `sd` | Punkt-für-Punkt-Scan starten |
| `sr` | Scan-Status: (Mode, geplante Pos., aktuelle Pos.) |
| `o` | Ist Achse am Ziel? (bool) |
| `s{x:.5f},{y:.5f},0` | Position zum Scan-Buffer hinzufügen |
| `a{angle_rad}` | Rotationswinkel setzen (rad, mit Mechanik-Offset) |
| `V{um_per_s}` | Achsengeschwindigkeit setzen |
| `V0` | Maximale Geschwindigkeit |
| `As` / `Ar` | Analog-Sampling starten/lesen |
| `Ss` / `Sr` | Positions-Sampling starten/lesen |
| `pa0,{x}` | Zielposition Achse 0 setzen (für Feedback-Enable) |
| `pa1,{y}` | Zielposition Achse 1 setzen |
**Scan-Status-Modi:**
- Mode 0: Direkte Positionierung (kein Scan aktiv)
- Mode 2: RT Point-Scan läuft
- Mode 3: RT Point-Scan startet
**Interferometer-Achsen** (aus `show_signal_strength_interferometer`):
- Achse 0: "ST FZP horizontal" (Zonenplatte, horizontal)
- Achse 1: "ST FZP vertical" (Zonenplatte, vertikal)
- Achse 2: Winkel-Interferometer (Rotation)
---
## 7. Galil Motor-Controller (OMNY)
**Typ:** Galil DMC-4080-D4140 (3 Einheiten für 19 Stages)
**Encoder:** Renishaw Tonic UHV
Funktionen:
- Closed-loop zum Encoder
- Following-Error-Überwachung (Schritt- vs. Encoderposition)
- Motortemperatur-Überwachung
- Automatische Reichweitenerweiterung der Tracking-Piezo-Stages
BEC-Treiber: `csaxs_bec/devices/omny/galil/`
---
## 8. Detektoren und Röntgenstrahl am cSAXS
### Röntgenstrahl
- **Undulator:** In-Vakuum, 19 mm Periode
- **Vertikale Quellgröße:** 20 µm
- **Sekundärquelle:** Spalt 20 µm breit, 12.1 m downstream vom Undulator
- **Monochromator:** Si(111) Doppelkristall (fixed-exit) + Fused-Silica-Spiegel
- **Typische Energie:** 6.2 keV (λ = 0.2 nm)
### Detektoren
| Detektor | Pixelgröße | Verwendung | Abstand (typisch) |
|---|---|---|---|
| Pilatus 2M | 172 µm | OMNY, LamNI | 7.33 m |
| Pilatus 300K | 172 µm | cSAXS Standard | variabel |
| Eiger 1.5M | 75 µm | Moderne OMNY/FlOMNI | variabel |
| JungFrauJoch (JFJ) | | Hochrate | variabel |
| IDS UI-524xCP-C | | OMNY Weitwinkel-Kamera | intern |
| IDS UI-548xCP-M | | OMNY Röntgen-Auge + Sichtbar | intern |
---
## 9. Gesamtvergleich der drei Setups
| Eigenschaft | LamNI | OMNY | FlOMNI |
|---|---|---|---|
| Methode | Ptych. Laminographie | Ptych. Tomographie (kryogen) | Ptych. Tomographie (RT) |
| Rotationsachse | 61° geneigt | 90° (senkrecht) | 90° (senkrecht) |
| Temperatur | Raumtemperatur | 90 K (LN₂) / 10 K (LHe) | Raumtemperatur |
| Vakuum | Nein | UHV (10⁻⁸ mbar) | Nein |
| Scan-Modus | Step (HW-getriggert) | Sync Fly-Scan | Async Fly-Scan |
| BEC-Basisklasse | `ScanBase` | `SyncFlyScanBase` | `AsyncFlyScanBase` |
| FOV (Scanning) | 12 mm × 12 mm (Stitch) | ~50 µm × 50 µm | 200 × 100 µm |
| Piezo (Probe) | Npoint NPXY100-216 | Delta-Scanner (PSI) | RT-Scanner |
| Piezo (FZP) | xyz-Stages (Steinm.) | Npoint NPXY100D + LC.403 | |
| Interferometer | Flachspiegel + Anti-Rotation | Tracking (Kugelspiegel) | Laser-Tracker |
| Positionsstabilität | 1.1 nm | < 10 nm | < 10 nm |
| Rotation BEC | `lsamrot` | `osamroy` | `fsamroy` |
| Flyer-Device | | `rt_omny` | `rt_positions` |
| Gewicht | 1 Tonne | 4 Tonnen | ähnlich |
| Beste Auflösung | 18.9 nm 3D | 8.5 nm 2D / 14.6 nm 3D | ~15 nm |
| Probenform | Flach/großflächig | Zylindrisch (OMNY Pins) | Zylindrisch |
| Probenmagazin | Nein | Load-Lock (6 Pins/Shuttle) | `flomni_sample_storage` |
| Scan-Min. Punkte | 20 (ScanAbortion sonst) | 20 | 20 |
---
## 10. Kritische Erkenntnisse für Softwareentwicklung
1. **LamNI ist LAMINOGRAPHIE** (61° geneigt), nicht Tomographie beeinflusst alle Positionsberechnungen
2. **Koordinatentransformation** im Code physikalisch begründet durch Stage-Verkippung (15°/60°)
3. **`rtx`/`rty`** = Piezo-Scanner in Interferometer-Koordinaten (µm), nicht Stage-Koordinaten
4. **`lsamx`/`lsamy`** = Koarse-Motoren (mm), werden auf read-only gesetzt bei aktivem Feedback
5. **nPoint** steuert bei OMNY die **FZP** (nicht Probe!), bei LamNI die **Probe**
6. **OMNY** hat einen eigenen Real-Time-Kernel (RTAI 4.0, 2.5 kHz) kommuniziert über Ethernet
7. **Anti-Rotations-Stage** ist mechanische Besonderheit von LamNI (passiv, Hebelarm)
8. **Tracking-Interferometer** (Holler & Raabe 2015) ist Schlüsseltechnologie für OMNY/FlOMNI
9. **FlOMNI** hat Laser-Tracker (nicht klassisches Tracking-Interferometer)
10. **DDG1** muss bei FlOMNI vor und nach Scan umgeschaltet werden (EXT_RISING_EDGE / SINGLE_SHOT)
11. **Trajektorie-Umkehr** (FlOMNI + OMNY) wird in Redis persistent gespeichert
12. Die Drift-Korrektur in LamNI läuft in bis zu **2 Iterationen**, Abbruch bei Drift > 150 µm
13. **Delta-Scanner (OMNY)**: Tripod-Geometrie → Rotationsmatrix notwendig für xyz-Kontrolle
14. **Attocube-Faserinterferometer**: Lokale Metrologie im Delta-Scanner (für schnelle PID-Schleife)
15. **OMNY Affine-Korrektur**: Einmalig pro Experimentrun bestimmt (Flipping-Experiment + FSC)
16. **OMNY Tracking-Stage y-Piezo** (ZSA-400-PSI, 400 µm, 200 Hz): ähnliche Eigenschaften wie Delta-Scanner daher geeignet für kontinuierliche Bewegung während Ptychographie
---
*Erstellt April 2026. Quellen: Quellcode csaxs_bec + 4 peer-reviewed Publikationen (Holler et al. 2012, 2015, 2018, 2020).*