Skip to content

jacotay7/pyturb

Repository files navigation

pyturb

CI PyPI Python Docs License: MIT

Documentation: jacotay7.github.io/pyturb

Fast, GPU-optional atmospheric turbulence for adaptive optics.

Animated Keck atmosphere showcase: frozen flow, boiling, and on/off-axis LGS turbulence.

pyturb generates the optical path differences (OPD) that an adaptive-optics system sees through the atmosphere: full layered turbulence for a representative sky, with per-layer wind, frozen-flow time evolution, off-axis directions, and standard site profiles. It runs on NumPy by default and switches to CUDA (via CuPy) with a single argument.

Install

pip install pyturb            # CPU (NumPy + SciPy)
pip install pyturb[cuda12]    # + CuPy for CUDA 12.x
pip install pyturb[cuda11]    # + CuPy for CUDA 11.x
pip install pyturb[accel]     # + Numba, faster CPU frozen flow

Quickstart

import pyturb

atm = pyturb.Atmosphere.from_profile(
    "paranal-median", seeing=0.8, zenith_angle=30, diameter=8.0, n=512, seed=1
)
print(atm.r0, atm.theta0, atm.tau0)      # Fried param, isoplanatic angle, tau0

for t, opd in atm.frames(dt=1e-3, steps=2000):
    ...                                   # (512, 512) OPD [m], frozen flow

ensemble = atm.sample(256)                # (256, 512, 512) Monte-Carlo OPDs

atm = pyturb.Atmosphere.from_profile("paranal-median", seeing=0.8, device="gpu")
for t, opd in atm.frames(dt=1e-3, steps=2000):
    ...                                   # cupy arrays, ~3,200 fps at 512^2

See Quickstart for off-axis/tomography, boiling, LGS, non-periodic frozen flow, and the lower-level PhaseScreen/InfinitePhaseScreen building blocks; and Concepts for r0, L0, Cn², θ0 and τ0 if you're new to AO.

Benchmarks

Full 9-layer Paranal atmosphere, closed-loop OPD frames/s, on an RTX 5090 (GPU) and a 32-core CPU (pyturb[accel]). The exact raw artifact and invocation are versioned with the benchmarks:

screen GPU spectral GPU extrude GPU Monte-Carlo screens/s CPU spectral CPU extrude
256² 3,219 4,489 104,981 1,014 2,571
512² 3,133 1,733 29,789 283 324
1024² 1,492 602 5,970 70 62

The Monte-Carlo column is Atmosphere.sample() — the full 9-layer atmosphere. Layers that share an outer scale are drawn as one aggregate screen (their PSDs add exactly), so a uniform-L0 profile costs one FFT, not nine: sample() now runs at nearly the single-layer PhaseScreen.generate rate (30,629 512² screens/s on the GPU, 108,054 at 256²). All Monte-Carlo figures are batched, device-resident throughput (a batch of 64 kept on the GPU); a single default call, or one that copies its result back to the host, is lower. Run python -c "import pyturb; pyturb.benchmark()" on your own machine, or python benchmarks/bench_suite.py for the full per-use-case sweep. A head-to-head against aotools, soapy and HCIPy lives in Comparison.

Features

  • Layered Atmosphere — named site profiles (paranal-median, mauna-kea, keck, las-campanas, HV 5/7, ...) or a custom Cn²(h) model, summed to pupil OPD with per-layer wind and airmass/zenith scaling.
  • Two frozen-flow enginesengine="spectral" (default): exact sub-pixel shift-theorem translation, all layers in one FFT, periodic. engine="extrude": Assémat–Wilson row extrusion, unbounded and non-periodic. Both use fused CUDA/Numba kernels on the hot path.
  • Off-axis / tomographyatm.opd(t, directions=[...]) batches several guide-star directions through one call.
  • Boiling — temporal decorrelation on top of frozen flow (tau_boil).
  • LGS cone effect — finite-range sodium beacon focal anisoplanatism (lgs_altitude).
  • Chromatic OPD — achromatic by default; dispersion="edlen"/"ciddor" for the dry-air/water-vapour term.
  • Diagnostics (pyturb.analysis) — Zernike decomposition, Noll (1976) mode variances, temporal PSD + power-law fit, angular decorrelation.
  • I/Opyturb.save/pyturb.load for FITS (optional astropy) and .npz, with provenance metadata.
  • GPU-optional — every class takes device="gpu" (CuPy); the GPU path is statistically identical to CPU (validated against the same theory to numerical precision). CuPy and NumPy have independent RNG streams, so a given seed draws a different realisation on each backend — the guarantee is matched statistics, not a bit-for-bit copy.
  • Validated against theory — structure function, Zernike spectrum, temporal PSD and angular decorrelation checked against analytic predictions in CI; see Validation.

See the API reference for every public function and class, and Interop for recipes with HCIPy, poppy, and DM-fitting loops.

License

MIT

About

Optimized, accurate, easy to use atmospheric phase screen generation.

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages