What’s New in Astropy 4.1?¶
Overview¶
Astropy 4.1 is a major release that contains bug fixes and new features since the 4.0.x series of releases.
In particular, this release includes:
A new SpectralCoord class for representing and transforming spectral quantities
Added True Equator Mean Equinox (TEME) frame for satellite two-line ephemeris data
Support for in-place setting of array-valued SkyCoord and frame objects
Change in the definition of equality comparison for coordinate classes
Support use of SkyCoord in table vstack, dstack, and insert_row
Support for table cross-match join with SkyCoord or N-d columns
Support for units on otherwise unitless models via the Model.coerce_units method.
In addition to these major changes, Astropy v4.0 includes a large number of smaller improvements and bug fixes, which are described in the Full Changelog. By the numbers:
211 issues have been closed since v4.0
275 pull requests have been merged since v4.0
62 distinct people have contributed code to this release, 25 of which are first time contributors to Astropy
A new SpectralCoord
class for representing and transforming spectral quantities¶
The Astronomical Coordinate Systems (astropy.coordinates) sub-package now includes a new SpectralCoord
class which can be used to represent spectral coordinates, and transform between
different velocity reference frames. It can be used for simple spectral
conversions:
>>> from astropy import units as u
>>> from astropy.coordinates import SpectralCoord, SkyCoord
>>> sc = SpectralCoord([654.2, 654.4, 654.6] * u.nm)
>>> sc
<SpectralCoord [654.2, 654.4, 654.6] nm>
>>> sc.to(u.micron)
<SpectralCoord [0.6542, 0.6544, 0.6546] micron>
>>> sc.to(u.eV)
<SpectralCoord [1.89520328, 1.89462406, 1.89404519] eV>
>>> sc.to(u.THz)
<SpectralCoord [458.25811373, 458.11805929, 457.97809044] THz>
It can also hold information about the observer and target:
>>> from astropy.time import Time
>>> from astropy.coordinates import EarthLocation
>>> location = EarthLocation.of_site('ALMA')
>>> alma = location.get_itrs(obstime=Time('2019-04-24T02:32:10'))
>>> ttau = SkyCoord('04h21m59.43s +19d32m06.4', frame='icrs',
... radial_velocity=23.9 * u.km / u.s,
... distance=144.321 * u.pc)
>>> sc_ttau = SpectralCoord([200, 250, 300] * u.GHz,
... observer=alma, target=ttau)
which then allows for example transforming these spectral values to different velocity frame, including for example to local standard of rest frames (the following example uses the Kinematic Local Standard of Rest definition):
>>> sc_ttau.with_observer_stationary_relative_to('lsrk')
<SpectralCoord
...
[200.01903338, 250.02379172, 300.02855007] GHz>
or to the rest frame of the target:
>>> sc_ttau.with_observer_stationary_relative_to(sc_ttau.target)
<SpectralCoord
...
[200.02737811, 250.03422264, 300.04106717] GHz>
For more information and examples, see Using the SpectralCoord Class.
Support for writing Dask arrays to FITS files¶
It is now possible to set the data array for PrimaryHDU
and ImageHDU
to a dask array.
If this is written to disk, the dask array will be computed as it is being
written, which will avoid using excessive memory:
>>> import dask.array as da
>>> array = da.random.random((1000, 1000))
>>> from astropy.io import fits
>>> hdu = fits.PrimaryHDU(data=array)
>>> hdu.writeto('test_dask.fits', overwrite=True)
Added True Equator Mean Equinox (TEME) frame for satellite two-line ephemeris data¶
The True Equator Mean Equinox (TEME
) frame has been added to
the built-in frames within astropy.coordinates.
For more details, see Working with Earth Satellites Using Astropy Coordinates.
Support for in-place setting of array-valued SkyCoord
and frame objects¶
Coordinate values in a array-valued SkyCoord
object can now be modified
in-place using the standard syntax for setting elements of a numpy array:
>>> sc1 = SkyCoord([1, 2] * u.deg, [3, 4] * u.deg)
>>> sc2 = SkyCoord(10 * u.deg, 20 * u.deg)
>>> sc1[0] = sc2
>>> sc1
<SkyCoord (ICRS): (ra, dec) in deg
[(10., 20.), ( 2., 4.)]>
For more details, see Modifying Coordinate Objects In-place.
Change in the definition of equality comparison for coordinate classes¶
When comparing coordinate SkyCoord
or frame objects using the equality
operators ==
or !=
, the result is now a boolean scalar or array
corresponding to the equality of the corresponding representation data
(including velocities if defined). The comparison is now done in a strict way
that requires all of the frame attributes and representation types to be
identical, where an exception is raised if that is not the case.
Previous to version 4.1, coordinate equality meant only that the two objects
were the same object. In other words, comparing two SkyCoord
objects
sc1 == sc2
was the same as writing sc1 is sc2
. Some astropy tests were
relying on this definition so you should check your package tests as well.
This updated equality operator is mostly useful for writing package tests. For most science analysis or processing work, you should check that the separation between the coordinates is below a specified angular distance.
For details see: Comparing SkyCoord Objects.
Support use of SkyCoord
in table vstack
, dstack
, and insert_row
¶
SkyCoord
mixin columns can now be used in table operations vstack
,
dstack
, and insert_row
(as long as they do not result in missing
values). This new functionality is a direct outcome of the new support for
setting SkyCoord
items in-place.
Support for table cross-match join with SkyCoord
or N-d columns¶
It is now possible to join two source catalog tables using a cross-match join
on the source coordinates (as SkyCoord
mixin columns) with an angular
separation matching tolerance. This can greatly simplify combining different
catalogs retrieved from astroquery or elsewhere.
This concept of a “fuzzy” join is also available for columns that represent
N-D cartesian points where the physical separation must be within a specified
threshold. This works with Quantity
mixin columns and normal 1-D or N-D
columns.
In all cases the cross-matching is done efficiently using a KD-Tree algorithm, and thus requires SciPy to be installed.
These join functions are built-in examples of a more generalized new functionality in table joining that allows users to create custom fuzzy join functions. An example would be to use natural language processing tools to join on words that are sufficiently similar.
For detais see Joining Coordinates and Custom Join Functions.
Support for custom attributes in Table
subclasses¶
One simple table customization that can be useful is adding new attributes to
the table object. This is easy enough, for example t.foo = 'hello'
, but this
attribute will be lost if the table is sliced, copied, pickled, or stored to
FITS or ECSV. In astropy 4.1 there is now an included mechanism to add custom
attributes which are persistent through all those normal operations.
For details see Adding Custom Table Attributes.
Added a new Time
subformat unix_tai
¶
A new Time
subformat unix_tai
has been added which is analogous to the
standard unix
time subformat but includes leap-seconds. This value matches
the definition for linux CLOCK_TAI.
For recent times (after about 1972) the unix_tai
value will differ from
unix
by the cumulative integral number of leap seconds since 1970-01-01 UTC.
There were 8.0 leap seconds in place at that time.
For details see: TimeUnixTai
.
Added support for the -TAB
convention in FITS WCS¶
astropy.wcs
is now able to read and interpret WCSs implementing the -TAB
convention as described in WCS Paper III
,
Greisen, E. W., Calabretta, M. R., Valdes, F. G., and Allen, S. L., Astronomy & Astrophysics, 446, 747-771, 2006.
Currently there is no support for programmatically constructing such WCSs.
Support for replacing submodels in CompoundModel
¶
It is now possible to create a new CompoundModel
by modifying an existing
one with the replace_submodel()
method. The replacement model can have an
arbitrary number of submodels. The only requirement is that the number of inputs
and outputs must match. The model to be replaced is identified by its name:
>>> from astropy.modeling import models
>>> m1 = models.Polynomial2D(2) & models.Polynomial2D(2)
>>> m2 = models.Rotation2D(21.3) | models.Pix2Sky_TAN()
>>> m2.name = "Rotate_and_Project"
>>> model = m1 | m2
>>> model_subst = models.Shift(1) & models.Shift(2)
>>> new_model = model.replace_submodel("Rotate_and_Project", model_subst | m2)
Support for units on otherwise unitless models via the Model.coerce_units
method.¶
A new coerce_units()
method provides a way to add input and return units to
a unitless model (e.g. polynomial) by enclosing it with two UnitsMapping
instances and returning a compound model.
>>> from astropy.modeling import models
>>> p = models.Polynomial1D(1, c0=1, c1=0)
>>> p_with_units = p.coerce_units({'x': u.m}, {'y': u.s})
>>> p_with_units(2 * u.m)
<Quantity 1. s>
Support for ASDF serialization of models¶
All models (excluding model sets) can be written to an ASDF file. Constraints
of type fixed
and bounds
can also be serialized.
Full change log¶
To see a detailed list of all changes in version v4.1, including changes in API, please see the Full Changelog.
Contributors to the v4.0 release¶
The people who have contributed to the code for this release are:
|
|
|
|
Where a * indicates their first contribution to the core astropy package.