Skip to content

Commit 07a12b1

Browse files
committed
WIP: try making dask do reprojection
1 parent 33cd6ff commit 07a12b1

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

spectral_cube/dask_spectral_cube.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,3 +1632,95 @@ def _mask_include(self):
16321632
chunks=self._data.chunksize),
16331633
wcs=self.wcs,
16341634
shape=self.shape)
1635+
1636+
def reproject(self, header, order='bilinear', use_memmap=False,
1637+
filled=True, **kwargs):
1638+
"""
1639+
Spatially reproject the cube into a new header. Fills the data with
1640+
the cube's ``fill_value`` to replace bad values before reprojection.
1641+
1642+
If you want to reproject a cube both spatially and spectrally, you need
1643+
to use `spectral_interpolate` as well.
1644+
1645+
.. warning::
1646+
The current implementation of ``reproject`` requires that the whole
1647+
cube be loaded into memory. Issue #506 notes that this is a
1648+
problem, and it is on our to-do list to fix.
1649+
1650+
Parameters
1651+
----------
1652+
header : `astropy.io.fits.Header`
1653+
A header specifying a cube in valid WCS
1654+
order : int or str, optional
1655+
The order of the interpolation (if ``mode`` is set to
1656+
``'interpolation'``). This can be either one of the following
1657+
strings:
1658+
1659+
* 'nearest-neighbor'
1660+
* 'bilinear'
1661+
* 'biquadratic'
1662+
* 'bicubic'
1663+
1664+
or an integer. A value of ``0`` indicates nearest neighbor
1665+
interpolation.
1666+
use_memmap : bool
1667+
If specified, a memory mapped temporary file on disk will be
1668+
written to rather than storing the intermediate spectra in memory.
1669+
filled : bool
1670+
Fill the masked values with the cube's fill value before
1671+
reprojection? Note that setting ``filled=False`` will use the raw
1672+
data array, which can be a workaround that prevents loading large
1673+
data into memory.
1674+
kwargs : dict
1675+
Passed to `reproject.reproject_interp`.
1676+
"""
1677+
1678+
try:
1679+
from reproject.version import version
1680+
except ImportError:
1681+
raise ImportError("Requires the reproject package to be"
1682+
" installed.")
1683+
1684+
reproj_kwargs = kwargs
1685+
# Need version > 0.2 to work with cubes, >= 0.5 for memmap
1686+
from distutils.version import LooseVersion
1687+
if LooseVersion(version) < "0.5":
1688+
raise Warning("Requires version >=0.5 of reproject. The current "
1689+
"version is: {}".format(version))
1690+
elif LooseVersion(version) >= "0.6":
1691+
pass # no additional kwargs, no warning either
1692+
else:
1693+
reproj_kwargs['independent_celestial_slices'] = True
1694+
1695+
from reproject import reproject_interp
1696+
1697+
# TODO: Find the minimal subcube that contains the header and only reproject that
1698+
# (see FITS_tools.regrid_cube for a guide on how to do this)
1699+
1700+
newwcs = wcs.WCS(header)
1701+
shape_out = tuple([header['NAXIS{0}'.format(i + 1)] for i in
1702+
range(header['NAXIS'])][::-1])
1703+
1704+
def reproject_interp_wrapper(img_slice):
1705+
# What exactly is the wrapper getting here?
1706+
# I think it is given a _cube_ that is a cutout?
1707+
if filled:
1708+
data = img_slice.filled_data[:]
1709+
else:
1710+
data = img_slice._data
1711+
return reproject_interp((data, img_slice.header),
1712+
newwcs, shape_out=shape_out, **kwargs)
1713+
1714+
newcube, newcube_valid = self.apply_function_parallel_spatial(
1715+
reproject_interp_wrapper,
1716+
accepts_chunks=True,
1717+
order=order,
1718+
**reproj_kwargs)
1719+
1720+
return self._new_cube_with(data=newcube,
1721+
wcs=newwcs,
1722+
mask=BooleanArrayMask(newcube_valid.astype('bool'),
1723+
newwcs),
1724+
meta=self.meta,
1725+
)
1726+

0 commit comments

Comments
 (0)