Skip to content

Releases

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 03 Nov 16:59
v0.5.0
fb9ba33

First stable release. Identical to 0.5.0rc2 apart from the version number;
the changes since 0.5.0rc1 are listed under 0.5.0rc2 below.

What's Changed

Full Changelog: v0.5.0rc2...v0.5.0

v0.5.0rc2

v0.5.0rc2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Nov 15:58
v0.5.0rc2
5789096

Second release candidate for 0.5.0. Changes since 0.5.0rc1:

Added

  • cosmology.lookback_time and cosmology.age (also as FLRW methods), and
    HUBBLE_TIME_GYR.
  • weighting="energy" for synthetic_photometry and
    synthetic_photometry_bands; vega_spectrum and vega_zero_point from the
    packaged CALSPEC alpha_lyr_stis_012 spectrum.
  • G23, F19 and GCC09 extinction laws (law="g23", "f19", "gcc09"). They
    raise outside their calibrated wavelength and R_V ranges.
  • sphere.pixwin computes the HEALPix pixel window (T and P) for any nside up
    to 8192 and l up to 4·nside, instead of shipping nside 8/16 tables.
  • torchsky.wcs.WCSHeaderWarning for header interpretations that go beyond
    the literal CTYPE.
  • API reference for gaussian_nll and poisson_gaussian_nll.
  • Real-data examples: MaNGA IFU cube, Legacy Surveys multi-band field fit,
    Gaia forced photometry against Tractor; the distortions guide uses real
    HST SIP and DECam TPV headers.
  • More real-data examples: JWST SMACS 0723 NIRCam coadd checked against the
    MAST mosaic; Legacy Surveys g/r/i/z on sparse HEALPix maps; a MaNGA cube
    rebuilt from fibre spectra; Gaia DR3 Pleiades proper motions in the
    Galactic frame; SFD dust at Gaia positions with G23; SDSS photometric
    redshifts with the experimental encoders; SDSS/GALEX/eFEDS footprint
    algebra with MOCs. TAP and SQL query snapshots are pinned by sha256.

Changed

  • WCS: SIP coefficients without a -SIP CTYPE, and ambiguous TAN+PV
    headers, raise ValueError. TAN with SCAMP PVi_m (m ≥ 5) is read as TPV
    with a WCSHeaderWarning.
  • observed_altaz always applies precession; TT−UTC defaults to the built-in
    leap-second table and raises outside it.
  • coadd_healpix integrates the exact image overlap for HEALPix cells coarser
    than the kernel support, so cells larger than the image no longer drop out.
  • HEALPix mapmaking applies the FK5→ICRS frame bias, with
    CelestialFrameBiasWarning, instead of treating FK5 as ICRS.
  • Planck power-spectrum example: apodised Galactic mask, monopole and dipole
    removal, w₂ normalisation.

Fixed

  • Integer amin/amax scatters on MPS (MOC normalisation, one-to-one
    crossmatch, connected components, response bit planes) no longer need 64-bit
    Metal atomics, which some Apple GPUs lack ("Failed to create pipeline state
    object"); they reduce in int32 when values fit and on the CPU otherwise.
  • Without the compiled extension (and on MPS), query_disc, RING
    query_polygon and SphericalPolygon.pixelize no longer scan every sky
    pixel: a torch quadtree descent selects the same pixels as the native path
    in O(boundary cells x depth + output). A 1.6-arcmin polygon at NSIDE 2^12
    took 38 s and now takes 0.02 s; NSIDE 2^16 takes 0.04 s. RING polygons whose
    centroid lies outside them also no longer scan the full sky with the
    extension.
  • SparseHealpixMap with nside_coverage no longer allocates a dense
    lookup block of (nside / nside_coverage)**2 values per covered coverage
    cell when that exceeds eight slots per stored pixel; such maps look values
    up by binary search on the sorted pixels. A sparse NSIDE 2^19 coadd needed
    6 GiB per map and ran out of memory on a 10.75 GiB GPU.
  • IFU drizzle with aperture_diameter_arcsec: spaxels that a fibre misses or
    only touches got rounding-noise weights (~1e-16) that differed between CPU
    and CUDA and switched whole spaxels on or off. Overlap fractions within the
    computation's rounding bound (64 eps) are now zero.
  • MPS: moving an MPS tensor to CPU float64/complex128 in one .to(device, dtype), torch.as_tensor or .to(other) call returns zeros in PyTorch
    2.14. Every such conversion in torchsky now moves first and casts on the
    target device; a test keeps fused conversions out of src/.
  • WCS: TPV PV1_3/PV1_4 are no longer read as LONPOLE/LATPOLE; DECam
    fields were mirrored about CRVAL.
  • spectral_axis_from_header and SpectralReader.read_data_cube read
    CDi_i and PCi_i·CDELTi and apply -LOG, -F2W, -V2W and grism
    codes through the WCS; unsupported codes raise. MaNGA cubes were truncated
    at 8184 Å instead of 10354 Å.
  • SkyConfig(mode="per_exposure") works on images no larger than the mesh.
  • Passband.to("mps") holds the curve in float32 instead of raising.
  • MOC.read_fits reads IVOA MOC files without EXTNAME='MOC' (the table in
    the first extension with ORDERING='NUNIQ', as CDS publishes them); time
    MOCs and non-ICRS coverage raise.
  • build_ifu_cube and plan_ifu_cube_response are vectorised: the same plans
    as before, 780k MaNGA samples in about 10–80 s instead of 30–40 min.
  • IFUObservation.aperture_diameter_arcsec gives fibre spectra exact circular
    footprints; drizzle without a footprint raises for samples with no
    neighbour in their own slice, instead of borrowing one from another slice.
  • IFUSliceWCS.to works around a PyTorch 2.14 MPS bug where an MPS float32 to
    CPU float64 copy returns zeros.
  • Scalar R_V and E(B-V) in extinction.a_lambda are built in the
    wavelength dtype, with no float32 round-trip.
  • The Horsehead example draws the MOC boundary its caption describes.
  • Coadd weights with interpolation kernels (bicubic, Lanczos, Catmull-Rom,
    Mitchell-Netravali) renormalise the kernel taps that fall off an input image,
    so a constant inverse-variance map keeps its value up to the edge. Lanczos3
    gave up to 1.2× the input inverse variance next to an edge (0.98 instead of
    0.81 in the maps overview), which also over-weighted that exposure in the
    mean. The fix covers coadd, coadd_cube, coadd_healpix and blot;
    inverse_variance stays the exact variance of the linear estimate.
  • exact_intersection, exact_union and exact_difference on polygons, caps
    and multipolygons return a SphericalBooleanRegion instead of a
    NativeApproximateSphericalRegion whose area() raised.
    SphericalBooleanRegion.area() is the exact area of polygon combinations,
    clipped from the great-circle edges; caps, boxes and ellipses raise
    ValueError. exact_area() and native to_exact regions use it.
  • SphericalMultiPolygon.area() counts overlapping members once; it summed
    them. SphericalCap.area() returns the analytic cap area.

What's Changed

Full Changelog: v0.5.0rc1...v0.5.0rc2

v0.5.0rc1

v0.5.0rc1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Nov 17:10
v0.5.0rc1
d070ef1

First public release of torchsky: a torch-native astronomy stack for sky
coordinates, geometry, maps, observation operators, scenes, and field models.
FITS file and table I/O is provided by the separate
torchfits package, a required
dependency.

Supported lanes

  • Python 3.12, 3.13 and 3.14 (full CI suite on each, plus macOS for 3.14).
  • PyTorch 2.14; torchfits 1.3.1 or newer.
  • CPU, CUDA 13 and newer (PyTorch cu130, validated on an NVIDIA H100), and
    Apple MPS.
  • Linux x86_64 and macOS 14+ arm64 wheels.

What torchsky provides

  • WCS (torchsky.wcs): FITS WCS for celestial, spectral, and time axes with
    every standard projection, SIP, TPV, TNX/ZPX, paper-IV lookup tables, -TAB
    axes, exact Jacobians, footprints, and astrometric fitting; batched,
    differentiable, and device-aware.
  • Coordinates (torchsky.coords): CatalogState with proper motion,
    parallax, radial velocity, and epochs; geometric frame conversion; observed
    place (ERFA Earth ephemeris, aberration, light deflection, refraction)
    through explicit EarthOrientation and Site.
  • Sphere (torchsky.sphere): HEALPix pixelization (RING and NEST),
    queries that descend the quadtree, spherical regions, MOC and sparse maps,
    spherical harmonic transforms (scalar and spin) with lmax up to
    3*nside-1, and a healpy-shaped torchsky.sphere.compat namespace.
  • Catalogs (torchsky.catalogs): sky-indexed cone search and crossmatch with
    best1, best2, mutual, symmetric, and all modes, per-row errors,
    join_rows, exact matching, self-matching groups, and multi-catalog
    matching, with exact pair-set parity with STILTS on Gaia DR3 x 2MASS x AllWISE.
  • Mapmaking (torchsky.map): planned resampling and coaddition (Lanczos,
    bilinear, nearest, exact square drizzle), weights, masks, DQ and variance
    propagation, automatic memory-budget tiling, HEALPix maps, and IFU cubes
    (coadd_cube) with flux-conserving spectral rebinning.
  • Spectra and photometry: spectral axes, relativistic Doppler shifts,
    passbands and synthetic photometry, dust extinction laws, and differentiable
    FLRW cosmology.
  • Scenes and fields (torchsky.scene, torchsky.field): observation
    operators, source-catalog scenes, continuous field models, chromatic PSF
    fields, and fitting; the native response and likelihood layer is experimental.
  • ML and tooling: torchsky.transforms and torchsky.encoders, the
    torchsky command line, and torchsky.viz all-sky figures
    (plot_healpix_sky, plot_sky_grid) on Mollweide, Aitoff, Hammer, and polar
    projections.
  • The package ships py.typed.

Highlights

  • 135 JWST/NIRCam exposures (566 Mpix) coadded onto a 5025 x 5025 grid: Lanczos-3
    in 221 s on CPU and 65 s on a GPU slice; exact drizzle in 149 s on CPU and
    148 s on GPU. Drizzle output matches STScI drizzle to better than 2e-6 sigma.
  • A 280-CCD CFHT/MegaCam tile coadd onto 10k x 10k pixels in 711 s on CPU and
    660 s on a GPU slice with automatic tiling and no out-of-memory failures.
  • SIP forward, inverse, and Jacobian use nested Horner evaluation (JWST order-5
    SIP, 4 M points: distort 15x and Newton inverse 4x faster than a power stack).
  • Observed place agrees with erfa.atco13 to 0.012 mas.

Measurement environments and full tables are on the
Performance highlights page.

Known limitations

  • The native response/likelihood layer and torchsky.map.solvers are
    experimental and do not establish calibrated real-sky response.
  • On a 5025 x 5025 grid, CPU Lanczos-3 is slower than SWarp; the GPU run is
    faster.
  • MPS float32 cannot reach half a pixel on very fine WCS grids; a
    PrecisionWarning is raised.
  • Resampling between FK5 (J2000) and ICRS emits CelestialFrameBiasWarning
    (about 20-30 mas); set RADESYS = 'ICRS' on headers solved against Gaia.
  • Irregular spectral axes in coadd_cube use index-space interpolation with a
    recorded bias envelope.

torchsky continues the sky-geometry part of torchfits ≤ 0.3.1; see the torchfits changelog for earlier history.

What's Changed

  • feat: allow schema override for integer types in to_tensor_frame by @sfabbro in #8
  • ⚡ Bolt: [performance improvement] Vectorize contiguous range finding by @sfabbro in #10
  • feat: handle FITS writing for torch_frame VLA, embeddings, and temporal stypes by @sfabbro in #13
  • 🧪 Add map command tests by @sfabbro in #18
  • 🧪 [testing improvement] Add comprehensive tests for sphere MOC by @sfabbro in #22
  • 🧪 Add test suite for WCS cylindrical projections by @sfabbro in #9
  • ⚡ Bolt: Vectorize fourier features generation loop by @sfabbro in #11
  • ⚡ Bolt: Vectorize and Optimize Bandpass Features Generation by @sfabbro in #12
  • 🧪 Add tests for datasets module base by @sfabbro in #14
  • 🧪 Add tests for TableChunkDataset by @sfabbro in #15
  • ⚡ Bolt: cache FITS filename extension check by @sfabbro in #16
  • 🧪 Add test suite for healpix_image_plane map projections by @sfabbro in #17
  • 🧹 [code health improvement] Analyze unused warnings import by @sfabbro in #19
  • 🧹 [code health] Allow schema override for TensorFrame conversion by @sfabbro in #20
  • 🧪 Add test coverage for FFT affine LDU module by @sfabbro in #21
  • 🛡️ Sentinel: [HIGH] Fix insecure deserialization in torch.load by @sfabbro in #28
  • ⚡ Bolt: Vectorize log spectral Fourier feature encoding by @sfabbro in #24
  • 🧹 [code health improvement description] - False Positive: Unused re import in table.py by @sfabbro in #25
  • 🧹 Fix bare pass in exception handler in torchsky.table by @sfabbro in #63
  • 🛡️ Sentinel: [CRITICAL] Fix insecure deserialization by @sfabbro in #62
  • 🧹 Move benchmark_header_parsing out of main source code by @sfabbro in #61
  • 🧹 Remove unused _apply_cpu_scale function by @sfabbro in #57
  • 🧪 [testing improvement] Add test for _can_use_mmap_row_path_for_full_read with exception by @sfabbro in #55
  • 🧪 [testing improvement] Add unit tests for _finalize_crossmatch by @sfabbro in #54
  • 🧪 Add test for is_compatible_arrow_table edge cases by @sfabbro in #53
  • 🧹 [code health] Remove unused log_errors decorator by @sfabbro in #51
  • 🧪 [testing improvement] Add test for create_inference_transform by @sfabbro in #50
  • 🧪 [testing improvement] Add test for create_validation_transform by @sfabbro in #48
  • 🛡️ Sentinel: [CRITICAL/HIGH] Fix Command Injection Vulnerability by @sfabbro in #45
  • 🧹 [code health improvement] Remove unused import in fft_resample.py by @sfabbro in #44
  • ⚡ Bolt: [performance improvement] Unroll fits metadata header loop by @sfabbro in #43
  • 🛡️ Sentinel: [CRITICAL/HIGH] Fix CFITSIO Command Injection Vulnerability by @sfabbro in #41
  • 🧪 [testing improvement] Add edge case test for _uniq_to_ranges with empty tensor by @sfabbro in #39
  • 🧪 [testing improvement] Cover different types of empty tensors in MOC functions by @sfabbro in #37
  • ⚡ Bolt: Replace torch.square with element-wise multiplication by @sfabbro in #36
  • 🧪 [testing improvement] Add error handling tests for table reading heuristics by @sfabbro in #35
  • 🎨 Palette: Add focus states and ARIA roles to viz UI by @sfabbro in #34
  • 🧹 Remove unused annotations import in device.py by @sfabbro in #31
  • 🛡️ Sentinel: [CRITICAL/HIGH] Fix XSS vulnerability in visualization frontend by @sfabbro in #83
  • ⚡ Bolt: Optimize schema header parsing with fast TFIELDS loop by @sfabbro in #82
  • 🎨 Palette: [UX improvement] Add focus rings and fix empty state direction by @sfabbro in #81
  • ⚡ Bolt: [performance improvement] Optimize chunked loops in catalog crossmatching by @sfabbro in #80
  • ⚡ Bolt: [performance improvement] Optimize nn.Linear initialization loops by @sfabbro in #79
  • 🧹 Refactor read to reduce massive cyclomatic complexity by @sfabbro in #78
  • 🧹 Code Health: Remove unused module_compute_device utility by @sfabbro in #77
  • ⚡ Bolt: Optimize module type check in _reset_silu_mlp_linears by @sfabbro in #76
  • 🧹 Refactor read_image to reduce cyclomatic complexity by @sfabbro in #75
  • ⚡ Bolt: [performance improvement] by @sfabbro in...
Read more