Source code for pvextractor.pvextractor

from __future__ import print_function

import numpy as np
import warnings

from astropy import units as u
from astropy.extern import six
from astropy.io.fits import PrimaryHDU, ImageHDU, Header

from .utils.wcs_utils import get_spatial_scale, sanitize_wcs
from .geometry import extract_slice
from .geometry import path as paths
from .utils.wcs_slicing import slice_wcs


[docs]def extract_pv_slice(cube, path, wcs=None, spacing=1.0, order=3, respect_nan=True): """ Given a position-position-velocity cube with dimensions (nv, ny, nx), and a path, extract a position-velocity slice. Alternative implementations: gipsy::sliceview karma::kpvslice casaviewer::slice Parameters ---------- cube : :class:`~numpy.ndarray` or :class:`~spectral_cube.SpectralCube` or str or HDU The cube to extract a slice from. If this is a plain :class:`~numpy.ndarray` instance, the WCS information can optionally be specified with the ``wcs`` parameter. If a string, it should be the name of a file containing a spectral cube. path : `Path` or list of 2-tuples The path along which to define the position-velocity slice. The path can contain coordinates defined in pixel or world coordinates. wcs : :class:`~astropy.wcs.WCS`, optional The WCS information to use for the cube. This should only be specified if the ``cube`` parameter is a plain :class:`~numpy.ndarray` instance. spacing : float The position resolution in the final position-velocity slice. This can be given in pixel coordinates or as a :class:`~astropy.units.Quantity` instance with angle units. order : int, optional Spline interpolation order when using paths with zero width. Does not have any effect for paths with a non-zero width. respect_nan : bool, optional If set to `False`, NaN values are changed to zero before computing the slices. If set to `True`, in the case of line paths a second computation is performed to ignore the NaN value while interpolating, and set the output values of NaNs to NaN. Returns ------- slice : `PrimaryHDU` The position-velocity slice, as a FITS HDU object """ if isinstance(cube, (six.string_types, ImageHDU, PrimaryHDU)): try: from spectral_cube import SpectralCube cube = SpectralCube.read(cube) except ImportError: raise ImportError("spectral_cube package required for working " "with fits data. Install spectral_cube or " "use NumPy arrays") if _is_spectral_cube(cube): wcs = cube.wcs # The fits HEADER will preserve the UNIT, but pvextractor does not care # what the flux units are cube = cube.filled_data[...].value if wcs is not None: wcs = sanitize_wcs(wcs) if not isinstance(cube, np.ndarray) or wcs is not None: scale = get_spatial_scale(wcs) if isinstance(spacing, u.Quantity): pixel_spacing = (spacing / scale).decompose() world_spacing = spacing else: pixel_spacing = spacing world_spacing = spacing * scale else: if isinstance(spacing, u.Quantity): raise TypeError("No WCS has been specified, so spacing should be given in pixels") else: pixel_spacing = spacing world_spacing = None # Allow path to be passed in as list of 2-tuples if not isinstance(path, paths.Path): path = paths.Path(path) pv_slice = extract_slice(cube, path, wcs=wcs, spacing=pixel_spacing, order=order, respect_nan=respect_nan) # Generate output header if wcs is None: header = Header() else: header = slice_wcs(wcs, spatial_scale=world_spacing).to_header() # TODO: write path to BinTableHDU return PrimaryHDU(data=pv_slice, header=header)
def _is_spectral_cube(obj): try: from spectral_cube.spectral_cube import BaseSpectralCube return isinstance(obj, BaseSpectralCube) except ImportError: if 'SpectralCube' in (obj.__class__): warnings.warn("Object appears to be a SpectralCube, but" " the spectral_cube module could not be loaded") return False