Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HDU to Projection #376

Merged
merged 4 commits into from
Apr 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
0.4.1 (unreleased)
------------------
- Add creating a Projection from a FITS HDU
(https://github.com/radio-astro-tools/spectral-cube/pull/376)
- Deprecate numpy <=1.8 because nanmedian is needed
(https://github.com/radio-astro-tools/spectral-cube/pull/373)
- Add tools for masking bad beams in VaryingResolutionSpectralCubes
Expand Down
31 changes: 31 additions & 0 deletions spectral_cube/cube_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from astropy.io.fits import BinTableHDU, Column
from astropy import units as u
import itertools
import re


def _fix_spectral(wcs):
"""
Expand Down Expand Up @@ -361,3 +363,32 @@ def _map_context(numcores):
finally:
if parallel:
p.close()


def convert_bunit(bunit):
'''
Convert a BUNIT string to a quantity

Parameters
----------
bunit : str
String to convert to an `~astropy.units.Unit`

Returns
-------
unit : `~astropy.unit.Unit`
Corresponding unit.
'''

# special case: CASA (sometimes) makes non-FITS-compliant jy/beam headers
bunit_lower = re.sub("\s", "", bunit.lower())
if bunit_lower == 'jy/beam':
unit = u.Jy
else:
try:
unit = u.Unit(bunit)
except ValueError:
warnings.warn("Could not parse unit {0}".format(bunit))
unit = None

return unit
24 changes: 24 additions & 0 deletions spectral_cube/lower_dimensional_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .io.core import determine_format
from . import spectral_axis
from .utils import SliceWarning
from .cube_utils import convert_bunit

import numpy as np

Expand Down Expand Up @@ -185,6 +186,29 @@ def __new__(cls, value, unit=None, dtype=None, copy=True, wcs=None,

return self

@staticmethod
def from_hdu(hdu):
'''
Return a projection from a FITS HDU.
'''

if not len(hdu.shape) == 2:
raise ValueError("HDU must contain two-dimensional data.")

meta = {}

mywcs = wcs.WCS(hdu.header)

if "BUNIT" in hdu.header:
unit = convert_bunit(hdu.header["BUNIT"])
meta["BUNIT"] = hdu.header["BUNIT"]
else:
unit = None

self = Projection(hdu.data, unit=unit, wcs=mywcs, meta=meta,
header=hdu.header)

return self

def quicklook(self, filename=None, use_aplpy=True, aplpy_kwargs={}):
"""
Expand Down
20 changes: 4 additions & 16 deletions spectral_cube/spectral_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,7 @@ def __init__(self, data, wcs, mask=None, meta=None, fill_value=np.nan,
raise TypeError("If a header is given, it must be a fits.Header")

if 'BUNIT' in self._meta:

# special case: CASA (sometimes) makes non-FITS-compliant jy/beam headers
bunit = re.sub("\s", "", self._meta['BUNIT'].lower())
if bunit == 'jy/beam':
self._unit = u.Jy


else:
try:
self._unit = u.Unit(self._meta['BUNIT'])
except ValueError:
warnings.warn("Could not parse unit {0}".format(self._meta['BUNIT']))
self._unit = None
self._unit = cube_utils.convert_bunit(self._meta["BUNIT"])
elif hasattr(data, 'unit'):
self._unit = data.unit
else:
Expand Down Expand Up @@ -2927,13 +2915,13 @@ def identify_bad_beams(self, threshold, reference_beam=None,
for prop in criteria:
val = props[prop]
mid = getattr(reference_beam, prop)

diff = np.abs((val-mid)/mid)

assert diff.shape == includemask.shape

includemask[diff > threshold] = False

return includemask

def mask_out_bad_beams(self, threshold, reference_beam=None,
Expand Down
13 changes: 13 additions & 0 deletions spectral_cube/tests/test_projection.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,16 @@ def test_quantity_property():

assert isinstance(arr, u.Quantity)
assert not isinstance(arr, OneDSpectrum)


@pytest.mark.parametrize(('LDO', 'data'),
zip(LDOs_2d, data_two_2d))
def test_projection_from_hdu(LDO, data):

p = LDO(data, copy=False)

hdu = p.hdu

p_new = LDO.from_hdu(hdu)

assert (p == p_new).all()