pypi galpy 1.12.0
Version 1.12.0

4 hours ago

This release contains several major new additions — the full 3D variational equations with Lyapunov exponents, the MultipoleExpansionPotential for arbitrary density distributions, smooth StreamTrack models for tidal streams, and a complete rewrite of the documentation as tested Jupyter notebooks — along with many new features, bug fixes, and dependency/project maintenance updates.

Major changes

  • 3D variational equations (state-transition matrix) + Lyapunov by @jobovy with Claude in #891:

    galpy now supports the full 3D variational equations (the state-transition matrix) during orbit integration in C, the 3D analogue of the existing planar machinery, for most of the potential library. This enables fast tangent-dynamics and chaos calculations — including the new Orbit.lyapunov method for estimating the largest Lyapunov exponent (or, with spectrum=True, the full Lyapunov spectrum) — and lays the groundwork for differentiable orbit integration. The variational equations also support velocity-dependent (dissipative) forces such as dynamical friction.

  • Add MultipoleExpansionPotential for multipole expansion of arbitrary densities by @jobovy with Claude in #829:

    The new MultipoleExpansionPotential represents the potential of an arbitrary, and optionally time-dependent, density distribution through a real spherical-harmonic multipole expansion, with both Python and C evaluation of the potential, forces, second derivatives, and density; it can be built directly from a density function via the from_density classmethod. A companion DiskMultipoleExpansionPotential uses it to solve the Poisson equation for disk+halo systems (the multipole analogue of DiskSCFPotential).

  • Smooth stream track for streamspraydf models by @jobovy with Claude in #861

  • df.streamdf: streamTrack method + deprecate calc_stream_lb (and Rnorm/Vnorm) by @jobovy with Claude in #878:

    A new StreamTrack class holds a smooth, precomputed phase-space track through a tidal stream, with accessors for every standard galpy coordinate system, an analytic 6×6 phase-space covariance along the track, and built-in plotting. Tracks can be built from a particle sample or generated directly from a streamspraydf or streamdf via their new streamTrack methods.

  • Rewrite tutorials as Jupyter notebooks with gallery navigation by @jobovy with Claude in #851:

    The documentation tutorials have been completely rewritten as Jupyter notebooks with gallery-style navigation. The notebooks are executed as part of the test suite and periodically re-rendered, so the documentation is automatically verified against the current code and stays up to date.

New Features

  • Add DiskMultipoleExpansionPotential by @jobovy with Claude in #838
  • Add analytical power-law spherical distribution functions by @jobovy with Claude in #844
  • Add time-dependent MultipoleExpansionPotential by @jobovy with Claude in #847
  • Add tail= keyword to streamspraydf, deprecate leading= by @jobovy with Claude in #849
  • Vectorize EllipsoidalPotential evaluations to support array inputs by @jobovy with @Copilot and Claude in #858
  • Per-orbit time arrays in Orbit.integrate; batched streamspraydf integration by @jobovy with Claude in #873
  • Add align_to_orbit helper to coords + Orbit by @jobovy with Claude in #874
  • df.streamspraydf: allow callable, time-dependent progenitor_mass by @jobovy with Claude in #880
  • df.streamspraydf: non-uniform stripping-time distributions + pericenter helper by @jobovy with Claude in #881
  • Add cinterp option to NonInertialFrameForce for fast C orbit integration by @jobovy with Claude in #889
  • actionAngleStaeckel: pure-Python (c=False) frequencies and angles by @jobovy with Claude in #1010
  • Add ExpTruncNFWPotential: exponentially-truncated NFW profile by @sgpfaff with Claude in #976

Bug fixes and minor tweaks

  • Fix in-place mutation of input arrays in coordinate transformation functions by @jobovy with @Copilot in #842
  • Fix p(v|r) interpolator grid not covering full rmax range by @jobovy with Claude in #846
  • Fix incorrect physical unit conversion for phitorque in DissipativeForce and planarDissipativeForce by @jobovy with @Copilot in #853
  • Propagate turn_physical_on/off to CompositePotential components by @jobovy with @Copilot in #855
  • Try to deal with flakiness of the stepsize test by @jobovy in #875
  • df.streamdf: rename custom_transform → custom_sky_transform by @jobovy in #879
  • Fix incorrect SpiralArms C R2deriv/PlanarR2deriv used by integrate_dxdv by @jobovy with Claude in #899
  • Fix incorrect power of R in TwoPowerSpherical C PlanarR2deriv by @jobovy with Claude in #902
  • Fix incorrect coefficient in FlattenedPowerPotential C PlanarR2deriv by @jobovy with Claude in #912
  • Fix sign of SCFPotential C planar 2nd derivatives (variational STM) by @jobovy with Claude in #923
  • SCFPotential: analytic second derivatives (replace numerical mixin) by @jobovy with Claude in #921
  • Fix interpolation-range warning for multiple orbits by @jobovy with Claude in #924
  • DiskSCF family: planar 2nd derivatives in C (planar variational equations) by @jobovy with Claude in #925
  • Fix: KuijkenDubinski layer drops t for the embedded expansion (time-dependent DiskMultipole frozen at t=0) by @jobovy with Claude in #943
  • Fix list-of-Potential input to wrapper potentials: upgrade through _check_potential_list_and_deprecate by @jobovy with Claude in #947
  • Fix wrapper repr for direct WrapperPotential subclasses (eaten first character) by @jobovy with Claude in #948
  • Fix silent-skip in _parse_pot: planarized potentials without planar C support segfaulted the C integrator by @jobovy with Claude in #953
  • RotateAndTiltWrapperPotential C: include t in the force-cache key by @jobovy with Claude in #954
  • Support astropy ≥ 8: galcen_v_sun is now a CartesianRepresentation (.xyz) by @jobovy with Claude in #971
  • Fix deepcopy of MultipoleExpansionPotential under scipy>=1.18 by @jobovy with Claude in #980
  • Fix numpy 2.5.0 compatibility (eig/eigvals complex + chararray deprecation) by @jobovy with Claude in #994
  • Fix sphericaldf sampling crash for slightly-negative isotropic DFs by @jobovy with Claude in #1032

Dependencies / maintenance

  • Fix release date in 1.11.2 release by @jobovy in #833
  • Bump version to next development version by @jobovy in #834
  • Increase MACOSX_DEPLOYMENT_TARGET to 11.0 because latest llvm-openmp requires that (see llvm/llvm-project#176094) by @jobovy in #836
  • Bump the actions group with 2 updates by @dependabot[bot] in #835
  • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci[bot] in #837
  • Bump pypa/cibuildwheel from 3.3 to 3.4 in the actions group by @dependabot[bot] in #839
  • Update vendored xsf from v0.1.3 to v0.2.0 by @jobovy with @Copilot in #843
  • Bump the actions group with 2 updates by @dependabot[bot] in #845
  • Bump mymindstorm/setup-emsdk from 14 to 15 in the actions group by @dependabot[bot] in #848
  • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci[bot] in #850
  • Bump mymindstorm/setup-emsdk from 15 to 16 in the actions group by @dependabot[bot] in #859
  • Remove old rst documentation replaced by notebook tutorials by @jobovy with Claude in #860
  • Staeckel tutorial: pyvo fallback for flaky Gaia archive by @jobovy with Claude in #863
  • Add monthly workflow to re-execute documentation notebooks by @jobovy with Claude in #862
  • Fix dry_run boolean comparison in update-doc-notebooks workflow by @jobovy with Claude in #865
  • Bump the actions group with 2 updates by @dependabot[bot] in #866
  • Use emscripten-core/setup-emsdk action by @jobovy with Claude in #867
  • Replace archived jakejarvis/s3-sync-action with AWS CLI by @jobovy with Claude in #868
  • Expand documentation notebook coverage by @jobovy with Codex and Claude in #869
  • Restore doc images mistakenly removed in #860 by @jobovy with Claude in #871
  • Cache Gaia DR3 query result in staeckel doc notebook by @jobovy with Claude in #870
  • Cache Dierickx 2010 catalog in orbit/examples notebook to reduce CI flakes by @jobovy with Claude in #876
  • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci[bot] in #877
  • CI: use runner's preinstalled Miniconda instead of setup-micromamba by @jobovy with Claude and Codex in #882
  • CI: update-doc-notebooks workflow should only stage .ipynb files by @jobovy with Claude in #884
  • Add updating the doc notebooks to the release checklist by @jobovy in #887
  • Reproducible doc-notebook re-renders + Claude diff summary in PR body by @jobovy with Claude in #886
  • [auto] Update documentation notebook outputs (2026-05-16) by @github-actions[bot] in #888
  • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci[bot] in #890
  • Bump the actions group with 2 updates by @dependabot[bot] in #915
  • CI: remove the unused 'ci skip' commit-message guard by @jobovy with Claude in #955
  • tests: fix pytest 9.1.0 collection error (list(zip(...)) in parametrize) by @jobovy with Claude in #957
  • Bump pypa/cibuildwheel from 4.0 to 4.1 in the actions group by @dependabot[bot] in #958
  • tests: parametrize the per-potential loop-tests in test_potential.py by @jobovy with Claude in #977
  • Add an 'all-clear' aggregate status check for auto-merge / merge queue by @jobovy with Claude in #979
  • Bump actions/checkout from 6 to 7 in the actions group by @dependabot[bot] in #995
  • [auto] Update documentation notebook outputs (2026-06-15) by @github-actions[bot] in #961
  • Bump actions/cache from 5 to 6 in the actions group by @dependabot[bot] in #1030
  • Add truncated-NFW N-body sampling examples to spherical_dfs tutorial by @jobovy with Claude in #1031
  • [auto] Update documentation notebook outputs (2026-06-30) by @github-actions[bot] in #1035
  • Release 1.12.0 by @jobovy with Claude in #1037
  • Bump version to 1.12.0 by @jobovy in #1041

New Contributors

  • @github-actions[bot] made their first contribution in #888
  • @sgpfaff made their first contribution in #976

Full Changelog: v1.11.2...v1.12.0

Don't miss a new galpy release

NewReleases is sending notifications on new releases.