Skip to main content

Learned mass-conserving deprojection of galaxy images -> 3D stellar density, rotation curve, potential.

Project description

Disk Galaxy Deprojection

This repository builds a baseline-plus-residual probabilistic benchmark for deprojecting barred-galaxy stellar mass structure from S4G-like images.

For project background, current Milestone 2b status, and continuation guidance, start with docs/reports/2026-06-10-project-handoff.md.

Deprojecting a galaxy image — the dgdp package

dgdp turns a galaxy image into its deprojected 3-D stellar-mass distribution, rotation curve, and (optionally) gravitational potential, using a bundled pretrained model — no training data or GPU required.

Install

pip install git+https://github.com/lucyundead/disk-galaxy-deprojection

Core install is light (numpy, astropy, matplotlib) and ships the ~1 MB model. Retraining the model additionally needs the TNG table and the [train] extra (pip install '.[train]').

Quickstart

Python:

from dgdp import deproject
r = deproject("galaxy.fits", distance_mpc=15.2, inclination_deg=30, pa_onsky_deg=153,
              ml=1.0, stellar_mass=6e10, n_samples=48)
r.density_3d              # (nR, nphi, nz) cylindrical stellar-mass cube [Msun]
r.v_circ([1, 2, 5, 10])   # rotation curve at those radii [km/s]
r.scale_height([1, 5, 10])       # sech^2 scale height h_z(R) [kpc] (rho ∝ sech²(z/h_z))
r.scale_height_samples([1, 5])   # posterior draws (n_samples, nR) -> uncertainty bands
r.rms_z([1, 5, 10])       # RMS|z|(R) moment [kpc] (tail-weighted; h_z is the obs-comparable one)
r.v_circ_samples([1, 5])  # same for the rotation curve
r.reproj["history"]       # reprojection-consistency residual (see below)
r.edge_on, r.face_on      # 2-D renderings
r.regrid(n_r=256, n_phi=192, n_z=128)   # same model re-evaluated on a finer grid (hydro ICs:
                          # vertical + m<=4 terms are analytic; only Sigma(R,phi) interpolates)
r.save("out/")            # density.npz + rotation_curve.csv + deprojection.png

CLI:

dgdp-deproject galaxy.fits --distance-mpc 15.2 --inclination-deg 30 --pa-onsky-deg 153 \
    --ml 1.0 --stellar-mass 6e10 -o out/

Geometry & M/L

  • Geometry: give pix_arcsec + pa_pix_deg (+ center) to bypass WCS (e.g. an S4G cutout), or let a FITS WCS supply the pixel scale and convert an on-sky pa_onsky_deg.
  • The deprojected shape is M/L-independent; M/L only sets the v_c amplitude. Fix the absolute scale with either (a) stellar_mass (total M*, M/L already folded in), (b) luminosity × ml, or (c) zeropoint + band_solar_mag + distance to calibrate the image to a luminosity. With none of these the outputs use a relative scale.

Potential (optional)

r.potential(R, z) and dgdp-deproject --potential return the AGAMA CylSpline potential Φ(R,z). AGAMA is not pip-installable — build it from source (https://github.com/GalacticDynamics-Oxford/Agama) and put it on PYTHONPATH; everything else works without it.

Method

The in-plane surface density is anchored geometrically from the image; a learned fixed-dictionary sech² vertical profile q_m(z;R) — trained on 185 TNG50 barred galaxies × 198 projections — supplies the thickness, mass-conserving by construction. See docs/reports/2026-06-30-mixture-qm-fixed-dictionary.md.

The learned vertical profiles cover m ∈ {0, 2, 4}; the remaining azimuthal content of the surface density (spiral arms, odd m) is carried with the local m=0 vertical profile — being φ-mean-free it changes no ring mass and no RMS|z|(R), but keeps the arms in the maps and lets the reprojection loop drive the image residual to the discretization floor.

Two consistency layers on top:

  • Reprojection loop (reproject_iters, default 2): the thick reconstruction is projected back to the sky and the Σ anchors are corrected until the model actually reproduces the observed image (the plain geometric stretch assumes zero thickness). Early-stops with revert, so it never returns a worse-reprojecting model; r.reproj["history"] holds the obs-weighted mean |log(obs/model)| per pass and r.reproj["ratio"] the final residual map.
  • Posterior sampling (n_samples): the bundled model is a mixture density network; sampling its head propagates the vertical-profile posterior to RMS|z|(R) and v_c(R) bands (rms_z_samples / v_circ_samples). Band coverage is calibrated on the held-out TNG50 val split (src/dgdp/models/dgdp_fixed_dict.calibration.json).

Milestone 1 predicts posterior residuals for physical summaries:

  • radial stellar mass profile
  • radial surface-density profile
  • vertical scale-height summary
  • bar thickness summary
  • bar amplitude summary
  • central concentration summary

Start with:

python -m pytest -q
python scripts/build_synthetic_benchmark.py --config configs/milestone1.synthetic.toml
python scripts/train_summary_residual_mdn.py --data outputs/milestone1_synthetic/residual_table.npz
python scripts/evaluate_summary_residual.py --run-dir outputs/milestone1_synthetic

Synthetic Milestone 1 Benchmark

Run the synthetic benchmark:

python scripts/build_synthetic_benchmark.py --config configs/milestone1.synthetic.toml
python scripts/train_summary_residual_mdn.py --data outputs/milestone1_synthetic/residual_table.npz --output-dir outputs/milestone1_synthetic
python scripts/evaluate_summary_residual.py --run-dir outputs/milestone1_synthetic

The benchmark writes:

  • outputs/milestone1_synthetic/manifest.csv
  • outputs/milestone1_synthetic/residual_table.npz
  • outputs/milestone1_synthetic/summary_residual_mdn.pt
  • outputs/milestone1_synthetic/normalization.npz
  • outputs/milestone1_synthetic/metrics.json

Milestone 2 Cluster TNG50 Ingestion

Milestone 2 runs TNG-facing work on the remote cluster through the existing HPC wrapper at /home/lucyundead/codex/hpc-agent/hpc.

python scripts/cluster_dgdp.py sync
python scripts/cluster_dgdp.py check-env
python scripts/cluster_dgdp.py reproduce-milestone1
python scripts/cluster_dgdp.py run-tng50
python scripts/cluster_dgdp.py run-tng50-density
python scripts/cluster_dgdp.py fetch-tng50

The cluster workflow keeps full TNG50 snapshots remote and fetches only compact artifacts under outputs/tng50_milestone2/. If local rsync is unavailable, the project CLI falls back to archive transfer through the HPC wrapper and does not delete remote files.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

disk_galaxy_deprojection-0.4.2.tar.gz (921.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

disk_galaxy_deprojection-0.4.2-py3-none-any.whl (886.8 kB view details)

Uploaded Python 3

File details

Details for the file disk_galaxy_deprojection-0.4.2.tar.gz.

File metadata

  • Download URL: disk_galaxy_deprojection-0.4.2.tar.gz
  • Upload date:
  • Size: 921.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for disk_galaxy_deprojection-0.4.2.tar.gz
Algorithm Hash digest
SHA256 20168d4d69cf1213eb30ee119d12311216cab0373c042656cc8319d3c27aeb86
MD5 33ce9c7014f67c29b567dd88bedd45ad
BLAKE2b-256 23441a2126b2acc5b6dc11512524794da415f8cb7eb10b3d2c766dc461091d3b

See more details on using hashes here.

Provenance

The following attestation bundles were made for disk_galaxy_deprojection-0.4.2.tar.gz:

Publisher: release.yml on lucyundead/disk-galaxy-deprojection

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file disk_galaxy_deprojection-0.4.2-py3-none-any.whl.

File metadata

File hashes

Hashes for disk_galaxy_deprojection-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 dc557ba9db3633d7f40be4a18529693ac38fba2aae902be9e8d1e6181351868f
MD5 e253c5dc9d0033e5344c1206eff3c14f
BLAKE2b-256 6ed5a6ff58594e71be52e92fe4a8dcc956e88321f7e94347f419e3ea36387fc7

See more details on using hashes here.

Provenance

The following attestation bundles were made for disk_galaxy_deprojection-0.4.2-py3-none-any.whl:

Publisher: release.yml on lucyundead/disk-galaxy-deprojection

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page