What’s New in Astropy 8.0?#

Overview#

Astropy 8.0 is a release that adds significant new functionality since the 7.2 release.

In particular, this release includes:

In addition to these major changes, Astropy v8.0 includes a large number of smaller improvements and bug fixes, which are described in the Full Changelog. By the numbers:

  • 934 commits have been added since 7.2

  • 141 issues have been closed since 7.2

  • 305 pull requests have been merged since 7.2

  • 68 people have contributed since 7.2

  • 35 of which are new contributors

Full change log#

To see a detailed list of all changes in version v8.0, including changes in API, please see the Full Changelog.

Cosmology#

The astropy.cosmology module has several updates in this release.

Module Simplification#

The deprecated module-level shim files in astropy.cosmology have been removed. These compatibility modules were originally deprecated in v7.1. With this release, all cosmology classes and functions must be imported directly from astropy.cosmology.

The following deprecated modules have been removed:

  • astropy.cosmology.connect

  • astropy.cosmology.core

  • astropy.cosmology.flrw

  • astropy.cosmology.funcs

  • astropy.cosmology.parameter

Migration Guide

If your code was still using the old import paths, you need to update them to import directly from astropy.cosmology.

Before:

from astropy.cosmology.flrw import FlatLambdaCDM
from astropy.cosmology.core import Cosmology
from astropy.cosmology.funcs import z_at_value

After:

from astropy.cosmology import Cosmology, FlatLambdaCDM, z_at_value

Cosmology Traits#

The traits module provides reusable components, called traits, that encapsulate specific cosmological properties or behaviors. For example, the NeutrinoComponent trait provides the neutrino component and related methods. By combining these traits, you can easily construct custom cosmology classes with precisely the features you need, without having to reimplement common functionality. Here is an example of how to use the NeutrinoComponent trait in custom cosmology classes:

>>> import numpy as np
>>> from astropy import units as u
>>> from astropy.cosmology import Cosmology
>>> from astropy.cosmology.traits import TemperatureCMB, NeutrinoComponent
>>> NEUTRINO_FERMI_DIRAC_CORRECTION = 0.22710731766  # 7/8 (4/11)^4/3
>>>
>>> class SimpleNeutrinoCosmology(Cosmology, TemperatureCMB, NeutrinoComponent):
...     '''Minimal cosmology demonstrating NeutrinoComponent trait.'''
...     def __init__(self, Tcmb0=2.7255, Neff=3.046, Ogamma0=5e-5):
...         self.Tcmb0 = u.Quantity(Tcmb0, "K")
...         self.Neff = Neff
...         self.Ogamma0 = Ogamma0
...         super().__init__()
...     @property
...     def has_massive_nu(self):
...         return False
...     @property
...     def Onu0(self):
...         return NEUTRINO_FERMI_DIRAC_CORRECTION * self.Neff * self.Ogamma0
...     def nu_relative_density(self, z):
...         return NEUTRINO_FERMI_DIRAC_CORRECTION * self.Neff * np.ones_like(np.asarray(z))
...     def Ogamma(self, z):
...         return self.Ogamma0 * (np.asarray(z) + 1.0) ** 4
...     @property
...     def is_flat(self):
...         return True
>>>
>>> cosmo = SimpleNeutrinoCosmology()
>>> cosmo.Tnu0
<Quantity 1.94... K>
>>> cosmo.has_massive_nu
False
>>> cosmo.Onu0
3.4...e-05
>>> cosmo.Onu(0)
np.float64(3.4...e-05)
>>> cosmo.Tnu(1)
<Quantity 3.89... K>

Machine Readable Table (MRT) I/O#

The astropy.cosmology module now supports reading and writing cosmological objects in the Machine Readable Table (MRT) format. This adds MRT to the existing I/O options for cosmology, which include YAML, ECSV, HTML, and LaTeX formats.

MRT format is commonly used in astronomical publications and data archives. You can now save and load cosmological parameters using the .read() and .write() methods with format="ascii.mrt":

from astropy.cosmology import Planck18

# Write to MRT file
Planck18.write("cosmology.mrt")

# Read from MRT file
cosmo = Cosmology.read("cosmology.mrt")

Note that since MRT format does not preserve table metadata, the cosmology class is included as a column in the table rather than in metadata (similar to HTML and LaTeX formats). Multi-dimensional columns (such as neutrino masses) are automatically JSON-encoded when writing and decoded when reading.

Angular diameter distance between two redshifts#

The angular_diameter_distance() method now accepts either one or two redshift arguments. When two redshifts are supplied, it returns the angular diameter distance from an object at z1 to an object at z2, replacing the use of the now-deprecated angular_diameter_distance_z1z2 method:

from astropy.cosmology import Planck18

Planck18.angular_diameter_distance(0.5)        # observer to z=0.5
Planck18.angular_diameter_distance(0.5, 2.0)   # z=0.5 to z=2.0

CODATA 2022 is now default in constants#

CODATA 2022 has replaced CODATA 2018 as default. astropyconst80 is available for constants science state, combining CODATA 2022 with IAU 2015. To use previous version of CODATA, see Collections of Constants (and Prior Versions).

Table formats#

A new table reader has been added to read history and profile output files from MESA, a well-known code for stellar evolution calculations.

Overhaul of cache and configuration path discovery mechanism#

Cache and configuration directories now adhere to the XDG specification by default. For example, the default cache location was changed from $HOME/.astropy/cache to $XDG_CACHE_HOME/astropy, where XDG_CACHE_HOME itself defaults to $HOME/.cache. Legacy cache and configuration default locations are still silently selected if present and in case the new default locations do not exist.

In addition, temporary directories set through set_temp_cache or set_temp_config will now not be symlinked to default locations. The new behavior is also meant as 100% cross platform: Windows isn’t special cased like it used to.

set_temp_cache and set_temp_config themselves (hereafter, legacy APIs) are now soft-deprecated, meaning their use is discouraged for new code but will not emit deprecation warnings, in favor of new, similar, but not drop-in replacement APIS: temporary_cache_dir_path and temporary_config_dir_path respectively. These alternative functions come with a couple differences in design:

  • easily predictable behavior

  • safer defaults:

    • temporary files and directories are not leaked by default (delete=True is the default)

    • pre-existing contents are never deleted (because the final dir is always created)

  • delete is keyword-only

  • dir_ (path) is positional only

  • support suffix and prefix

  • yield value is a pathlib.Path (not a str)

  • the namespace argument is keyword-only and required, whereas legacy API’s equivalent argument (rootname) was allowed positionally and defaulted to 'astropy', which contributed to confusion surrounding these APIs.

ASTROPY_CACHE_DIR and ASTROPY_CONFIG_DIR environment variables are now supported, allowing finer, tool-specific control as compared with XDG_CACHE_HOME and XDG_CONFIG_HOME which will only be used if astropy-specific environment variables are undefined or invalid (e.g., defined as relative paths or pointing to files).

Write table indices to FITS, HDF5 and ECSV formats#

It is now possible to write Table indices to FITS, HDF5, and ECSV formats and subsequently read them back in order to round-trip the original indexed table. This stores the index data as temporary columns in the output and includes other relevant metadata in the file output, similar to the mechanism for serializing mixin columns like SkyCoord.

This functionality is enabled by passing write_indices=True to the table write method. For example:

>>> import io
>>> from astropy.table import QTable
>>> t = QTable({"a": ["x", "z", "y"], "b": [2.0, 1.0, 1.5], "c": ["a", "b", "c"]})
>>> t.add_index("a")
>>> out = io.StringIO()
>>> t.write(out, format="ecsv", write_indices=True)
>>> t2 = QTable.read(out.getvalue(), format="ecsv")
>>> t2.loc["x"]
<Row index=0>
 a      b     c
str1 float64 str1
---- ------- ----
   x     2.0    a

Variable-length array logical columns in FITS#

Variable-length array columns of FITS logical type (PL/QL) are now read and written correctly. Previously, bool input was written as raw 1/0 bytes rather than the ASCII T/F bytes required by the FITS specification, and on read these columns were exposed as int8 arrays containing the byte values (84 for T, 70 for F) instead of as bool. Files written by astropy <= 7.2.0 are still readable: the legacy 0x00/0x01 encoding is auto-detected on read and decoded as bool, with an AstropyUserWarning so that users are aware the file does not strictly conform to the FITS standard.

For example:

>>> from astropy.io import fits
>>> col = fits.Column(name="a", format="PL", array=[[True, False, True]])
>>> hdu = fits.BinTableHDU.from_columns([col])
>>> hdu.writeto("example.fits", overwrite=True)
>>> fits.getdata("example.fits")["a"][0]
array([ True, False,  True])

Fast Lomb-Scargle: Low Rank Approximation#

The fast Lomb-Scargle Periodograms (fast and fastchi2 implementations) now use Low Rank Approximation (LRA) algorithm by default. The LRA implementation may be a little slower than the previous fast implementation (although this is architecture-dependent) but is 8 to 10 orders of magnitude more accurate, on par with their slow (non fast) counterparts.

This change of default allows eliminating previously seen issues with negative powers.

Preserving NULL values in FITS logical columns#

The FITS standard allows logical (L / PL / QL) column entries to take three byte values: b'T' (True), b'F' (False), or b'\x00' (undefined / NULL). Astropy has historically converted such columns to a numpy bool array on read, which silently maps NULL to False.

A new logical_as_bytes keyword argument has been added to open() (mirroring the existing character_as_bytes switch). When set to True, both fixed-length and variable-length logical columns are returned as |S1 byte arrays rather than bool, so b'\x00' is distinguishable from b'F'. Bytes read this way also round-trip through writing: a column read as |S1 and written back to a FITS file preserves NULL bytes verbatim.

A AstropyUserWarning is now also issued whenever a logical column being read with logical_as_bytes=False (the default) contains NULL bytes, alerting users to lost information.

Table display and pandas conversion#

Two improvements make tables with multidimensional columns easier to work with.

A new conf.multidim_threshold configuration option controls how multidimensional columns are displayed. Setting it to a small value (for example, 3) shows full content for short arrays such as 3-vectors ([1 2 3]), while larger arrays still fall back to the abbreviated first .. last representation.

In addition, to_pandas() now accepts tables with multidimensional columns: previously this would raise a ValueError, but they are now converted to 1D object arrays compatible with pandas.

FITS string column changes#

A few changes affect how string columns are read from FITS binary tables.

When reading FITS files via read(), the strip_spaces option now defaults to True, so trailing whitespace in fixed-width string columns is stripped automatically. Pass strip_spaces=False to recover the previous behavior.

In preparation for the deprecation of np.char.chararray in NumPy 2.5, astropy.io.fits will in a future release return ordinary NumPy arrays rather than chararray instances for string columns. Code that relies on chararray-specific methods (such as .rstrip() or .decode()) should migrate to the equivalent functions in np.strings.

New imshow_simple_norm convenience function#

A new imshow_simple_norm() function provides a compact one-call alternative to building a SimpleNorm/simple_norm and passing it to imshow, which is convenient for quick image previews:

from astropy.visualization import imshow_simple_norm

imshow_simple_norm(image, stretch="asinh", percent=99.5)

Parsing vector strings into Quantity#

It is now possible to construct a Quantity from a 1D vector-like string, with or without units:

from astropy import units as u

u.Quantity("[1, 2, 3] m")
u.Quantity("1, 2, 3", unit="m")

Deprecation of the built-in test runner#

The astropy.test() entry point and the TestRunner / TestRunnerBase classes are now formally deprecated and will be removed in a future release. Downstream packages that expose a packagename.test() function generated via TestRunner are affected and should migrate to invoking pytest directly. The previously deprecated astropy.tests.command module has been removed in this release.

NumPy 2.0 is now required#

The minimum supported NumPy version is now 2.0. Code and downstream packages that still rely on the NumPy 1.x C API or the Python-level behaviours that changed in NumPy 2.0 will need to be updated.

For users that cannot yet move to NumPy 2.0, the 7.2.x series of releases will continue to receive support for six months following the 8.0 release. That branch remains compatible with NumPy 1.

Contributors to the 8.0 release#

The people who have contributed to the code for this release are:

  • Adam Ginsburg

  • Aditya Lohuni *

  • Albert Y. Shih

  • Ana Clara Galvão *

  • Arthur Sardella *

  • Ben Green *

  • Bill Wolf *

  • Bodhi Silberling *

  • Brett Morris

  • Brigitta Sipőcz

  • Bruno Sanchez *

  • Charalampos Stratakis *

  • Clara Brasseur

  • Clément Robert

  • Curtis McCully

  • Cyrus *

  • Dhruv Yadav *

  • Duncan Macleod

  • Eero Vaher

  • Erik Tollerud

  • Evan Chen *

  • Fazeel Usmani *

  • Hans Moritz Günther

    1. Berg *

  • Jett Higgins *

  • Joren Hammudoglu *

  • Julian Harbeck *

  • Kacper Rutkowski *

  • Kang Wang

  • Kartavay Verma *

  • Kyle Oman

  • Larry Bradley

  • M Bussonnier *

  • Macdara Ó Murchú *

  • Marten van Kerkwijk

  • Maximilian Linhoff

  • Mohsin Mehmood

  • Nabil Freij

  • Nadia Dencheva

  • Naksh Yadav *

  • Nathaniel Starkman

      1. Lim

  • Pierre Sassoulas *

  • Preshanth Jagannathan

    1. Virinchi *

  • Raphael Erik Hviding

  • Reem Hamraz *

  • RinZ27 *

  • Simon Conseil

  • Stelios Voutsinas

  • Stuart Mumford

  • Surya K. *

  • Syn Pu *

  • Thomas Dutkiewicz *

  • Thomas Robitaille

  • Tiago Gomes

  • Tim Jenness

  • Tom Aldcroft

  • Varun Kasyap Pentamaraju *

  • Varun Nikam

  • Vishwas *

  • Wang Rui *

  • William Jamieson

  • Yaocheng Chen *

  • gilles.landais *

  • github-actions

  • xbreak *

  • Περικλής Παντελαίος *

Where a * indicates that this release contains their first contribution to astropy.