LabWired
회로 설계·펌웨어 실행·변형 비교·Playground 결과 확인, 오픈소스, 무료 체험
오프축 디지털 홀로그래피로 광랜턴의 파장 의존 전이 행렬을 자동 측정합니다
Automated measurement of a photonic lantern's wavelength-dependent transfer matrix by off-axis digital holography. UCF CREOL.
개발 도구Python · Jupyter NotebookGitHub @jeebuscrossaint온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기rinky dink program made by silica
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Automated measurement and analysis of the wavelength-dependent transfer matrix of a photonic lantern by off-axis digital holography — for Prof. Stephen Eikenberry's group at UCF CREOL.
A photonic lantern maps several single-mode fibers to the guided modes of a multimode fiber; that mapping is a complex-valued transfer matrix that evolves with wavelength. This software automates measurement of the encoding matrix: it sweeps the input port and wavelength, captures an off-axis hologram of the multimode output at each point, and recovers the complex field (amplitude and phase) for decomposition into LP modes — one row of the transfer matrix per measurement.
The reconstruction follows the method in:
C. Dobias, M. A. Römer, S. Bhargava, et al., "Wavelength-dependent evolution of full-field transfer matrices in photonic lanterns," Optics Express 34(9), 17217 (2026). https://doi.org/10.1364/OE.595908
| Component | Model | Interface |
|---|---|---|
| Tunable laser | HP/Agilent 8168E (1475–1575 nm) | GPIB · Keysight VISA |
| Camera | Xenics Bobcat 320 GigE (InGaAs, 320×256) | GigE Vision |
| Fiber switch | DiCon GP700 | RS-232 |
| Polarization | Thorlabs MPC320 (3 paddles) | USB · Kinesis |
The shipping app is a single native Windows executable — no Python, Node, server, or browser needed on the lab machine:
uv run python tools/build_app.py # -> dist/Digital Holography.exe
Copy dist/Digital Holography.exe to the lab PC and double-click. Connect
All → Start Experiment. Config, logs, and data are written next to the .exe.
Run from source instead (needs uv; no Node):
uv sync
./start.bat # = uv run python main.py
One-time per machine: install Keysight IO Libraries + Xenics Xeneth SDK and run the camera firewall rule — see LAB_SETUP.md.
holo/ is the library — every line of physics lives there. The desktop app and
the holo command are two front ends over it, and neither contains analysis
code of its own, so they can never drift apart.
holo/ THE LIBRARY
pipeline.py combines both engines — change processing here
data_processing.py single-frame reconstruction + LP decomposition
multiport_reconstruction.py cross-port (paper-fidelity) reconstruction + TM
fringe_detection.py fringe metric + polarization auto-optimizer
discovery.py folder -> records; frame loading and staging
config.py config loading
runtime.py frozen-build paths + Xeneth DLL bootstrap
cli.py the `holo` command
lib/ LP modes, FFT math, vendored Xeneth SDK
hardware/ drivers (laser, camera, switch, motors)
gui/ PySide6 (Qt6) app — window, tabs, acquisition loop
main.py GUI launcher (thin entry point)
tools/ build script + hardware probes
tests/ golden-file + unit tests (`uv run pytest`)
experiment_config.yaml instrument addresses + sweep parameters
docs/ setup guides (GigE camera, Xeneth SDK)
holo acquire -o ./run # sweep 1530-1560 nm, 3 exposures per point
holo process ./data # reconstruct a folder (up to 8 processes)
holo tm ./data -o tm.npz # reconstruct + export the transfer matrix
holo doctor # check the install, config and instruments
holo probe switch # talk to one instrument
holo gui # launch the desktop app
uv run holo <command>, or python -m holo without installing. Every command
takes --help. process.py still works as a deprecated shim for
holo process.
holo acquire drives only the laser and the camera — you connect the lantern
leg and set the paddles yourself, which is the usual way to take a single-leg
test. Everything is a flag; no config file to edit.
holo acquire --start 1530 --stop 1560 --step 1 -n 3 --leg 1 -o ./run
holo acquire --start 1530 --stop 1560 -n 3 --dry-run # print the plan, no hardware
-n 3 takes three exposures back to back at each wavelength and writes them to
run/rep01, run/rep02, run/rep03. They are separate folders on purpose:
frame discovery keeps one file per (leg, wavelength), so repeats sharing a
folder would leave all but one silently unprocessed. Each repNN is a complete
sweep — reconstruct one with holo process ./run/rep01.
Every frame gets a .png preview and a .yaml sidecar recording the commanded
and measured wavelength (the HP 8168E queues errors instead of raising, so a
rejected tune otherwise looks like a good frame at the wrong λ). Saturated
frames are flagged and the command exits non-zero — clipping makes intensity
nonlinear in the field, so both amplitude and phase are wrong.
Using it as a library:
from holo import HolographyDataProcessor, pipeline, discovery
records, cache = discovery.stage("./data", default_wl=1550)
rows = pipeline.process_records(HolographyDataProcessor(), records, config=cfg)
See CLAUDE.md for how the two reconstruction engines relate and where the physics lives.
Two engines, picked automatically by how much data the sweep has:
| single-frame | multiport | |
|---|---|---|
| module | data_processing.py | multiport_reconstruction.py |
| needs | one hologram | ≥ 2 legs across the sweep |
| carrier | per-frame sub-pixel centroid, demodulated to baseband | centroid averaged over all ports per λ, then linear-fit vs λ, then Fourier Fine-Binning |
| basis | per-frame optimum | optima consolidated across the sweep (paper Sec. 2) |
Both compute the paper's fidelity η = |⟨E_rec, E_S⟩ / (‖E_rec‖‖E_S‖)|² (Eq. 5). A multi-leg dataset runs both and keeps, per frame, whichever scored higher — so the result can never be worse than single-frame.
All fidelities below use the 8-mode basis unless stated otherwise, and each says how many frames it covers.
| data | frames | fidelity | notes |
|---|---|---|---|
| Jun 9 2026 sweep, port 1, 1525–1575 nm | 51 | 97.2 ± 0.5%, worst 95.8% | background-subtracted |
| Aug 4 2026 7-port sweep (Rumana Akhter), 1525–1569 nm | 215 of 315 | 92.7 ± 1.7%, worst 83.9% | 100 frames clip at 45000 counts and are excluded |
| Caleb's 19-port archive, multiport, 23 modes | 969 | 96.68 ± 1.58%, worst 80.0% | reproduces his own saved run (96.89%) |
| committed test frame | 1 | 0.9776 (8 modes), 0.9788 (15 modes) | GOLDEN_FIDELITY |
pipeline keeps the better engine per frame.tests/test_multiport.py. It skips unless the gitignored
dataset is unpacked to _caleb_ref/.Amarnath Patel (UCF Physics / CREOL, Eikenberry group), building on Caleb Dobias's original measurement and analysis work (see the paper above). The Aug 4 2026 7-port sweep was taken by Rumana Akhter with this software.