What’s New in Astropy 7.0?#

Overview#

Astropy 7.0 is a major release that adds significant new functionality since the 6.1 release.

In particular, this release includes:

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

  • X issues have been closed since v6.1

  • X pull requests have been merged since v6.1

  • X distinct people have contributed code

Full MaskedQuantity Support in QTable#

Masked quantities were already used in many table functions, like reading from files, and are now fully supported throughout, i.e., MaskedQuantity are now always used in QTable to represent masked quantities (or when the QTable is created with masked=True). This removes the last vestiges of a work-around where a normal Quantity was used with a stub of a mask, and fixes functions like reading of table data from a list of dict that includes quantities with missing entries, and aggregation of MaskedQuantity in table groups.

Coordinate frames can now be stored in tables#

Coordinate frames like ICRS and AltAz can now be stored in tables, as was already the case for SkyCoord and the underlying representations such as SphericalRepresentation.

This includes all frames, also those that do not have associated data, such as a SkyOffsetFrame in which the RA, Dec of the origin might represent a pointing directions for a tiled observation, and the position angle the roll of a spacecraft.

Quantity.to_string supports formatter for formatting#

The to_string() method now supports a formatter parameter. This feature supports both Python’s format specification mini-language via format strings and custom formatting through callables. This enables users to have explicit and consistent control over the numerical representation of quantities, accommodating a wide range of formatting needs.

Previously, the method primarily relied on the precision parameter for format control, which dictated the number of significant digits and did not provide much freedom in the latex format.

Example:

>>> from astropy import units as u
>>> q = u.Quantity(123.456, u.m)
>>> custom_format = lambda x: f"\\approx {float(x):.1f}"
>>> q.to_string(formatter=custom_format, format='latex')
'$\\approx 123.5 \\; \\mathrm{m}$'
>>> q.to_string(formatter='.3e', format='latex')
'$1.235 \\times 10^{2} \\; \\mathrm{m}$'
>>> q.to_string(precision=3, format='latex')
'$123 \\; \\mathrm{m}$'

NumPy constructor functions with a like argument are now supported with Quantity#

We added support for constructing Quantity arrays from 21 NumPy functions via the like keyword argument.

Example:

>>> import numpy as np
>>> from astropy import units as u
>>> q = u.Quantity(1.0, u.m)
>>> np.arange(0, 10, 1, like=q)
<Quantity [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] m>
>>> np.eye(3, like=q)
<Quantity [[1., 0., 0.],
           [0., 1., 0.],
           [0., 0., 1.]] m>
>>> np.full((3, 3), 1*u.s, like=q)
<Quantity [[1., 1., 1.],
           [1., 1., 1.],
           [1., 1., 1.]] s>

The unit of the output Quantity is defined from the first quantity argument where it is meaningful. Otherwise, and by default, the output unit will be that of the like argument itself.

Here’s the entire list of functions affected

Change default type for meta attribute to dict and update ECSV writer#

We have changed the default type for the meta attribute in Table and Column (and subclasses) from OrderedDict to dict. Since Python 3.8 the dict class is ordered by default, so there is no need to use OrderedDict.

In addition, the ECSV table writer in ASCII Tables (astropy.io.ascii) was updated to consistently write the meta attribute as an ordered map using the !!omap tag. This convention conforms to the ECSV specification and is supported by existing ECSV readers. Previously the meta attribute could be written as an ordinary YAML map, which is not guaranteed to preserve the order of the keys.

Improve the Contributor Documentation#

The Contributor documentation has been significantly improved. It now includes a Quickstart Guide with concise instructions on setting up a development environment and making a pull request. In addition, the developer documentation was reorganized and simplified where possible to improve readability and accessibility. We welcome continued feedback on how to make contributing to Astropy even easier and more enjoyable.

Typing in astropy.stats#

The astropy.stats module is now fully typed. This is the first subpackage for which this the case.

Converting units on dask and other array-like objects#

It is now possible to pass in array-like objects such as dask arrays as the value in Unit.to and have those arrays not be converted to Numpy arrays:

>>> from dask import array as da
>>> from astropy import units as u
>>> arr = da.arange(10)
>>> u.m.to(u.km, value=arr)
dask.array<mul, shape=(10,), dtype=float64, chunksize=(10,), chunktype=numpy.ndarray>

Note that it is not yet possible to use Quantity with dask arrays directly.

Fitting models in parallel with N-dimensional data#

A new function, parallel_fit_dask(), has been added to the astropy.modeling module. This function makes it easy to fit many parts of an N-dimensional array in parallel, such as fitting all the spectra in a spectral cube. This makes use of the dask package to efficiently parallelize the problem, running it either on multiple processes of a single machine or in a distributed environment. A simple example might be:

>>> from astropy.modeling.models import Gaussian1D
>>> from astropy.modeling.fitting import parallel_fit_dask, TRFLSQFitter
>>> model_fit = parallel_fit_dask(model=Gaussian1D(),
...                               fitter=TRFLSQFitter(),
...                               data=data,
...                               world=wcs,
...                               fitting_axes=0)

where data is a 3-D array, and wcs is the WCS object associated with the data. A full example can be found at Fitting models in parallel with N-dimensional data.

RGB image visualization enhancements#

The RGB image visualization functionality in astropy.visualization has been expanded to support more flexible methods for creating composite RGB images.

A new function make_rgb() allows for creating RGB images with independent scaling on each filter, using arbitrary stretch and interval functions (instances of subclasses of BaseStretch and BaseInterval, respectively).

Additionally, the make_lupton_rgb() function (which performs interconnected R, G, B image scaling) now also supports arbitrary stretch and interval functions, in addition to the default Lupton asihn stretch.

intervals = [ManualInterval(vmin=0, vmax=np.percentile(img,99.95)) for img in [i,r,g]]

rgb_log = make_rgb(i, r, g, interval=intervals, stretch=LogStretch(a=1000))
rgb_log_lupton = make_lupton_rgb(i, r, g, interval=intervals, stretch_object=LogStretch(a=5))

axes[0].imshow(rgb_log, origin='lower')
axes[1].imshow(rgb_log_lupton, origin='lower')

(png, svg, pdf)

../_images/7-0-2.png

New Lorentz2D model#

A new 2D Lorentzian model has been added to the astropy.modeling package.

Full change log#

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