Repository navigation
Releases
Releases · astroai/torchsky
v0.5.0
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
Second release candidate for 0.5.0. Changes since 0.5.0rc1:
Added
cosmology.lookback_timeandcosmology.age(also asFLRWmethods), and
HUBBLE_TIME_GYR.weighting="energy"forsynthetic_photometryand
synthetic_photometry_bands;vega_spectrumandvega_zero_pointfrom the
packaged CALSPECalpha_lyr_stis_012spectrum.- G23, F19 and GCC09 extinction laws (
law="g23","f19","gcc09"). They
raise outside their calibrated wavelength and R_V ranges. sphere.pixwincomputes 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.WCSHeaderWarningfor header interpretations that go beyond
the literalCTYPE.- API reference for
gaussian_nllandpoisson_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
-SIPCTYPE, and ambiguousTAN+PV
headers, raiseValueError.TANwith SCAMPPVi_m(m ≥ 5) is read as TPV
with aWCSHeaderWarning. observed_altazalways applies precession; TT−UTC defaults to the built-in
leap-second table and raises outside it.coadd_healpixintegrates 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/amaxscatters 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_polygonandSphericalPolygon.pixelizeno longer scan every sky
pixel: a torch quadtree descent selects the same pixels as the native path
inO(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. SparseHealpixMapwithnside_coverageno longer allocates a dense
lookup block of(nside / nside_coverage)**2values 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_tensoror.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 ofsrc/. - WCS: TPV
PV1_3/PV1_4are no longer read asLONPOLE/LATPOLE; DECam
fields were mirrored aboutCRVAL. spectral_axis_from_headerandSpectralReader.read_data_cuberead
CDi_iandPCi_i·CDELTiand apply-LOG,-F2W,-V2Wand 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_fitsreads IVOA MOC files withoutEXTNAME='MOC'(the table in
the first extension withORDERING='NUNIQ', as CDS publishes them); time
MOCs and non-ICRS coverage raise.build_ifu_cubeandplan_ifu_cube_responseare vectorised: the same plans
as before, 780k MaNGA samples in about 10–80 s instead of 30–40 min.IFUObservation.aperture_diameter_arcsecgives fibre spectra exact circular
footprints;drizzlewithout a footprint raises for samples with no
neighbour in their own slice, instead of borrowing one from another slice.IFUSliceWCS.toworks around a PyTorch 2.14 MPS bug where an MPS float32 to
CPU float64 copy returns zeros.- Scalar
R_VandE(B-V)inextinction.a_lambdaare 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 coverscoadd,coadd_cube,coadd_healpixandblot;
inverse_variancestays the exact variance of the linear estimate. exact_intersection,exact_unionandexact_differenceon polygons, caps
and multipolygons return aSphericalBooleanRegioninstead of a
NativeApproximateSphericalRegionwhosearea()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 nativeto_exactregions 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
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):CatalogStatewith proper motion,
parallax, radial velocity, and epochs; geometric frame conversion; observed
place (ERFA Earth ephemeris, aberration, light deflection, refraction)
through explicitEarthOrientationandSite. - 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) withlmaxup to
3*nside-1, and a healpy-shapedtorchsky.sphere.compatnamespace. - Catalogs (
torchsky.catalogs): sky-indexed cone search and crossmatch with
best1,best2,mutual,symmetric, andallmodes, 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.transformsandtorchsky.encoders, the
torchskycommand line, andtorchsky.vizall-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.atco13to 0.012 mas.
Measurement environments and full tables are on the
Performance highlights page.
Known limitations
- The native response/likelihood layer and
torchsky.map.solversare
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
PrecisionWarningis raised. - Resampling between FK5 (J2000) and ICRS emits
CelestialFrameBiasWarning
(about 20-30 mas); setRADESYS = 'ICRS'on headers solved against Gaia. - Irregular spectral axes in
coadd_cubeuse 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
readto 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...