Skip to content

Commit

Permalink
Merge pull request astropy#77 from astrofrog/improve-coverage
Browse files Browse the repository at this point in the history
Improve coverage
  • Loading branch information
astrofrog committed May 6, 2015
2 parents 54dbeaa + a7ce73c commit 5927519
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 27 deletions.
2 changes: 1 addition & 1 deletion reproject/array_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def iterate_over_celestial_slices(array_in, array_out, wcs):
def pad_edge_1(array):
try:
return np.pad(array, 1, mode='edge')
except: # numpy < 1.7 workaround
except: # numpy < 1.7 workaround pragma: no cover
new_array = np.zeros((array.shape[0] + 2,
array.shape[1] + 2),
dtype=array.dtype)
Expand Down
35 changes: 25 additions & 10 deletions reproject/healpix/tests/test_healpix.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@
from astropy.wcs import WCS
from astropy.tests.helper import pytest

from ..core import healpix_to_image, image_to_healpix
from ..high_level import reproject_from_healpix
try:
import healpy
HAS_HEALPY = True
except:
HAS_HEALPY = False

from ..high_level import reproject_from_healpix, reproject_to_healpix
from ...tests.test_high_level import ALL_DTYPES



DATA = os.path.join(os.path.dirname(__file__), 'data')


Expand All @@ -38,7 +45,7 @@ def get_reference_header(oversample=2, nside=1):
return reference_header


@pytest.mark.importorskip('healpy')
@pytest.mark.skipif('not HAS_HEALPY')
@pytest.mark.parametrize("nside,nested,healpix_system,image_system,dtype",
itertools.product([1, 2, 4, 8, 16, 32, 64], [True, False], 'C', 'C', ALL_DTYPES))
def test_reproject_healpix_to_image_round_trip(
Expand All @@ -55,20 +62,28 @@ def test_reproject_healpix_to_image_round_trip(
wcs_out = WCS(reference_header)
shape_out = reference_header['NAXIS2'], reference_header['NAXIS1']

image_data, footprint = healpix_to_image(
healpix_data, healpix_system, wcs_out, shape_out,
order=0, nested=nested)
image_data, footprint = reproject_from_healpix(
(healpix_data, healpix_system), wcs_out, shape_out=shape_out,
order='nearest-neighbor', nested=nested)

healpix_data_2, footprint = image_to_healpix(
image_data, wcs_out, healpix_system,
nside, order=0, nested=nested)
healpix_data_2, footprint = reproject_to_healpix(
(image_data, wcs_out), healpix_system,
nside=nside, order='nearest-neighbor', nested=nested)

np.testing.assert_array_equal(healpix_data, healpix_data_2)


@pytest.mark.importorskip('healpy')
@pytest.mark.skipif('not HAS_HEALPY')
def test_reproject_file():
reference_header = get_reference_header(oversample=2, nside=8)
data, footprint = reproject_from_healpix(os.path.join(DATA, 'bayestar.fits.gz'), reference_header)
reference_result = fits.getdata(os.path.join(DATA, 'reference_result.fits'))
np.testing.assert_allclose(data, reference_result)


@pytest.mark.skipif('not HAS_HEALPY')
def test_reproject_invalid_order():
reference_header = get_reference_header(oversample=2, nside=8)
with pytest.raises(ValueError) as exc:
reproject_from_healpix(os.path.join(DATA, 'bayestar.fits.gz'), reference_header, order='bicubic')
assert exc.value.args[0] == "Only nearest-neighbor and bilinear interpolation are supported"
62 changes: 62 additions & 0 deletions reproject/healpix/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import numpy as np

from astropy.tests.helper import pytest
from astropy.coordinates import FK5, Galactic, ICRS
from astropy.io import fits

try:
import healpy
HAS_HEALPY = True
except:
HAS_HEALPY = False

from ..utils import parse_coord_system, parse_input_healpix_data

def test_parse_coord_system():

frame = parse_coord_system(Galactic())
assert isinstance(frame, Galactic)

frame = parse_coord_system('fk5')
assert isinstance(frame, FK5)

with pytest.raises(ValueError) as exc:
frame = parse_coord_system('e')
assert exc.value.args[0] == "Ecliptic coordinate frame not yet supported"

frame = parse_coord_system('g')
assert isinstance(frame, Galactic)

with pytest.raises(ValueError) as exc:
frame = parse_coord_system('spam')
assert exc.value.args[0] == "Could not determine frame for system=spam"


@pytest.mark.skipif('not HAS_HEALPY')
def test_parse_input_healpix_data(tmpdir):

data = np.arange(3072)

col = fits.Column(array=data, name='flux', format="E")
hdu = fits.BinTableHDU.from_columns([col])
hdu.header['NSIDE'] = 512
hdu.header['COORDSYS'] = "G"

# As HDU
array, coordinate_system = parse_input_healpix_data(hdu)
np.testing.assert_allclose(array, data)

# As filename
filename = tmpdir.join('test.fits').strpath
hdu.writeto(filename)
array, coordinate_system = parse_input_healpix_data(filename)
np.testing.assert_allclose(array, data)

# As array
array, coordinate_system = parse_input_healpix_data((data, "galactic"))
np.testing.assert_allclose(array, data)

# Invalid
with pytest.raises(TypeError) as exc:
parse_input_healpix_data(data)
assert exc.value.args[0] == "input_data should either be an HDU object or a tuple of (array, frame)"
4 changes: 2 additions & 2 deletions reproject/healpix/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ def parse_coord_system(system):
elif system in FRAMES:
return FRAMES[system]
else:
system_new = frame_transform_graph.lookup_name(system)()
system_new = frame_transform_graph.lookup_name(system)
if system_new is None:
raise ValueError("Could not determine frame for system={0}".format(system))
else:
return system_new
return system_new()


def parse_input_healpix_data(input_data, field=0, hdu_in=None):
Expand Down
13 changes: 2 additions & 11 deletions reproject/spherical_intersect/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def parallel_impl(nproc):
array_new = sum([_.get()[0] for _ in results])
weights = sum([_.get()[1] for _ in results])

except KeyboardInterrupt:
except KeyboardInterrupt: # pragma: no cover
# If we hit ctrl+c while running things in parallel, we want to terminate
# everything and erase the pool before re-raising. Note that since we inited the pool
# with the _init_worker function, we disabled catching ctrl+c from the subprocesses. ctrl+c
Expand All @@ -190,15 +190,6 @@ def parallel_impl(nproc):
return array_new / weights, weights

if _method == "c" and (nproc is None or nproc > 1):
try:
return parallel_impl(nproc)
except KeyboardInterrupt:
# If we stopped the parallel implementation with ctrl+c, we don't really want to run
# the serial one.
raise
except Exception as e:
warnings.warn("The parallel implementation failed, the reported error message is: '{0}'".format(repr(e,)), AstropyUserWarning)
warnings.warn("Running the serial implementation instead", AstropyUserWarning)
return serial_impl()
return parallel_impl(nproc)

raise ValueError('unrecognized method "{0}"'.format(_method,))
2 changes: 1 addition & 1 deletion reproject/spherical_intersect/high_level.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ def reproject_exact(input_data, output_projection, shape_out=None, hdu_in=None,
wcs_out, shape_out = parse_output_projection(output_projection, shape_out=shape_out)

if wcs_in.has_celestial and wcs_in.naxis == 2:
return _reproject_celestial(array_in, wcs_in, wcs_out, shape_out=shape_out)
return _reproject_celestial(array_in, wcs_in, wcs_out, shape_out=shape_out, parallel=parallel)
else:
raise NotImplementedError("Currently only data with a 2-d celestial WCS can be reprojected using flux-conserving algorithm")
42 changes: 42 additions & 0 deletions reproject/spherical_intersect/tests/test_high_level.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst
from __future__ import (absolute_import, division, print_function,
unicode_literals)

import numpy as np
from astropy.io import fits
from astropy.wcs import WCS
from astropy.utils.data import get_pkg_data_filename
from astropy.tests.helper import pytest

from ..high_level import reproject_exact


class TestReprojectExact(object):

def setup_class(self):

self.header_in = fits.Header.fromtextfile(get_pkg_data_filename('../../tests/data/gc_ga.hdr'))
self.header_out = fits.Header.fromtextfile(get_pkg_data_filename('../../tests/data/gc_eq.hdr'))

self.header_out['NAXIS'] = 2
self.header_out['NAXIS1'] = 600
self.header_out['NAXIS2'] = 550

self.array_in = np.ones((100, 100))

self.wcs_in = WCS(self.header_in)
self.wcs_out = WCS(self.header_out)

def test_array_wcs(self):
reproject_exact((self.array_in, self.wcs_in), self.wcs_out, shape_out=(200, 200))

def test_array_header(self):
reproject_exact((self.array_in, self.header_in), self.header_out)

def test_parallel_option(self):

reproject_exact((self.array_in, self.header_in), self.header_out, parallel=1)

with pytest.raises(ValueError) as exc:
reproject_exact((self.array_in, self.header_in), self.header_out, parallel=-1)
assert exc.value.args[0] == "The number of processors to use must be strictly positive"
76 changes: 76 additions & 0 deletions reproject/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import numpy as np

from astropy.tests.helper import pytest
from astropy.coordinates import FK5, Galactic, ICRS
from astropy.io import fits
from astropy.wcs import WCS
from astropy.utils.data import get_pkg_data_filename

from ..utils import parse_input_data, parse_output_projection


def test_parse_input_data(tmpdir):

header = fits.Header.fromtextfile(get_pkg_data_filename('data/gc_ga.hdr'))

data = np.arange(200).reshape((10,20))

hdu = fits.ImageHDU(data)

# As HDU
array, coordinate_system = parse_input_data(hdu)
np.testing.assert_allclose(array, data)

# As filename
filename = tmpdir.join('test.fits').strpath
hdu.writeto(filename)

with pytest.raises(ValueError) as exc:
array, coordinate_system = parse_input_data(filename)
assert exc.value.args[0] == "More than one HDU is present, please specify HDU to use with ``hdu_in=`` option"

array, coordinate_system = parse_input_data(filename, hdu_in=1)
np.testing.assert_allclose(array, data)

# As array, header
array, coordinate_system = parse_input_data((data, header))
np.testing.assert_allclose(array, data)

# As array, WCS
wcs = WCS(hdu.header)
array, coordinate_system = parse_input_data((data, wcs))
np.testing.assert_allclose(array, data)

# Invalid
with pytest.raises(TypeError) as exc:
parse_input_data(data)
assert exc.value.args[0] == "input_data should either be an HDU object or a tuple of (array, WCS) or (array, Header)"



def test_parse_output_projection(tmpdir):

header = fits.Header.fromtextfile(get_pkg_data_filename('data/gc_ga.hdr'))
wcs = WCS(header)

# As header

with pytest.raises(ValueError) as exc:
parse_output_projection(header)
assert exc.value.args[0] == "Need to specify shape since output header does not contain complete shape information"

parse_output_projection(header, shape_out=(200, 200))

header['NAXIS'] = 2
header['NAXIS1'] = 200
header['NAXIS2'] = 300

parse_output_projection(header)

# As WCS

with pytest.raises(ValueError) as exc:
parse_output_projection(wcs)
assert exc.value.args[0] == "Need to specify shape when specifying output_projection as WCS object"

parse_output_projection(wcs, shape_out=(200, 200))
4 changes: 2 additions & 2 deletions reproject/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ def parse_input_data(input_data, hdu_in=None):
"""

if isinstance(input_data, six.string_types):
return parse_input_data(fits.open(input_data))
return parse_input_data(fits.open(input_data), hdu_in=hdu_in)
elif isinstance(input_data, HDUList):
if len(input_data) > 1:
if len(input_data) > 1 and hdu_in is None:
raise ValueError("More than one HDU is present, please specify HDU to use with ``hdu_in=`` option")
return parse_input_data(input_data[hdu_in])
elif isinstance(input_data, (PrimaryHDU, ImageHDU, CompImageHDU)):
Expand Down

0 comments on commit 5927519

Please sign in to comment.