reproject
The `reproject` package is a Python library designed for re-gridding astronomical images from one World Coordinate System (WCS) to another. It provides a uniform interface for various reprojection techniques, including interpolation-based methods, the adaptive and anti-aliased algorithm by DeForest (2004), and flux-conserving spherical polygon intersection. The library also supports reprojection to and from HEALPIX projections through integration with `astropy-healpix`. It is currently at version 0.19.0 and is actively maintained as part of the Astropy project, with a regular release cadence aligned with Astropy's development cycle.
Common errors
-
ValueError: The input WCS does not contain enough dimensions (expected 2, got X)
cause The `astropy.wcs.WCS` object provided for the input data does not have the expected number of celestial dimensions (typically 2 for images) that match the actual data array used for reprojection.fixVerify that your `WCS` object is correctly initialized with `naxis=2` (or the appropriate number of celestial axes) and that the celestial projection axes align with the dimensions of your input data array. When passing `(data, wcs)`, ensure `wcs` corresponds to the celestial dimensions of `data`. -
Reprojected image appears shifted, distorted, or misaligned from its expected position.
cause This is often caused by inaccuracies in the input or output WCS definitions, discrepancies in coordinate system datums (e.g., ICRS vs. FK5), or issues with the spherical representation of coordinates during transformation. It can also stem from an incorrect understanding of how projections work versus reprojection.fixCarefully inspect both the input and output `astropy.wcs.WCS` objects. Check all relevant FITS keywords (`CRVAL`, `CRPIX`, `CDELT`, `CTYPE`, `PC`, `CUNIT`, `RADECSYS`, `EQUINOX`) for correctness. Ensure consistent coordinate frames. If dealing with different datums, confirm that `astropy` is configured to handle the transformations correctly. Small errors in the WCS can lead to significant shifts.
Warnings
- gotcha The `reproject` library assumes that the input World Coordinate System (WCS) information is accurate. It performs image re-gridding, not image registration (alignment of images where WCS might be inaccurate).
- gotcha Interpolation-based reprojection (`reproject_interp`) is generally faster but does not guarantee flux conservation by default. For scientific applications requiring precise flux preservation, this can lead to incorrect results.
- gotcha When dealing with very large datasets, direct reprojection can consume significant memory. The `block_size` and `parallel` parameters are available for out-of-core and multi-threaded processing.
Install
-
pip install reproject -
conda install -c conda-forge reproject
Imports
- reproject_interp
from reproject import reproject_interp
- reproject_adaptive
from reproject import reproject_adaptive
- reproject_exact
from reproject import reproject_exact
- reproject_from_healpix
from reproject import reproject_from_healpix
- reproject_to_healpix
from reproject import reproject_to_healpix
Quickstart
import numpy as np
from astropy.wcs import WCS
from reproject import reproject_interp
import matplotlib.pyplot as plt
# 1. Create dummy input data and WCS
data_in = np.arange(100.0).reshape((10, 10)) + 100.0
wcs_in = WCS(naxis=2)
wcs_in.wcs.crpix = [5, 5]
wcs_in.wcs.cdelt = np.array([-0.1, 0.1])
wcs_in.wcs.crval = [0, 0]
wcs_in.wcs.ctype = ["RA---TAN", "DEC--TAN"]
# 2. Create target output WCS with a different projection/scale/rotation
wcs_out = WCS(naxis=2)
wcs_out.wcs.crpix = [10, 10]
wcs_out.wcs.cdelt = np.array([-0.05, 0.05]) # Different pixel scale
wcs_out.wcs.crval = [0, 0]
wcs_out.wcs.ctype = ["RA---TAN", "DEC--TAN"]
wcs_out.wcs.pc = [[np.cos(np.deg2rad(15)), -np.sin(np.deg2rad(15))],
[np.sin(np.deg2rad(15)), np.cos(np.deg2rad(15))]] # 15-deg rotation
shape_out = (20, 20) # Target output shape
# 3. Reproject the data using interpolation
data_out, footprint = reproject_interp((data_in, wcs_in), wcs_out, shape_out=shape_out)
# 4. Visualize the results (optional)
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1, projection=wcs_in)
plt.imshow(data_in, origin='lower', cmap='viridis')
plt.title('Original Data')
plt.xlabel('X (pixels)')
plt.ylabel('Y (pixels)')
plt.subplot(1, 2, 2, projection=wcs_out)
plt.imshow(data_out, origin='lower', cmap='viridis')
plt.title('Reprojected Data')
plt.xlabel('X (pixels)')
plt.ylabel('Y (pixels)')
plt.tight_layout()
plt.show()