From 16f60fd4a028b10bf8094bc84fb444d38c23aa33 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Wed, 6 May 2015 22:12:19 +0200 Subject: [PATCH] Improve test coverage --- reproject/array_utils.py | 2 +- reproject/healpix/tests/test_healpix.py | 14 ++--- reproject/healpix/tests/test_utils.py | 55 +++++++++++++++++++ reproject/healpix/utils.py | 4 +- reproject/spherical_intersect/core.py | 13 +---- reproject/spherical_intersect/high_level.py | 2 +- .../tests/test_high_level.py | 42 ++++++++++++++ 7 files changed, 110 insertions(+), 22 deletions(-) create mode 100644 reproject/healpix/tests/test_utils.py create mode 100644 reproject/spherical_intersect/tests/test_high_level.py diff --git a/reproject/array_utils.py b/reproject/array_utils.py index fa69a9a7a..e8bab95fe 100644 --- a/reproject/array_utils.py +++ b/reproject/array_utils.py @@ -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) diff --git a/reproject/healpix/tests/test_healpix.py b/reproject/healpix/tests/test_healpix.py index af54213f1..9f6761873 100644 --- a/reproject/healpix/tests/test_healpix.py +++ b/reproject/healpix/tests/test_healpix.py @@ -10,8 +10,7 @@ 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 +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') @@ -55,19 +54,20 @@ 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, + image_data, footprint = reproject_from_healpix( + (healpix_data, healpix_system), wcs_out, shape_out=shape_out, order=0, 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=0, nested=nested) np.testing.assert_array_equal(healpix_data, healpix_data_2) @pytest.mark.importorskip('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')) diff --git a/reproject/healpix/tests/test_utils.py b/reproject/healpix/tests/test_utils.py new file mode 100644 index 000000000..609fd1fdc --- /dev/null +++ b/reproject/healpix/tests/test_utils.py @@ -0,0 +1,55 @@ +import numpy as np + +from astropy.tests.helper import pytest +from astropy.coordinates import FK5, Galactic, ICRS +from astropy.io import fits + +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" + + +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)" diff --git a/reproject/healpix/utils.py b/reproject/healpix/utils.py index 2af3683c3..d3bd591c6 100644 --- a/reproject/healpix/utils.py +++ b/reproject/healpix/utils.py @@ -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): diff --git a/reproject/spherical_intersect/core.py b/reproject/spherical_intersect/core.py index c8a0dcaca..fc2e53536 100644 --- a/reproject/spherical_intersect/core.py +++ b/reproject/spherical_intersect/core.py @@ -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 @@ -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,)) diff --git a/reproject/spherical_intersect/high_level.py b/reproject/spherical_intersect/high_level.py index 46f90ef87..2bb58f355 100644 --- a/reproject/spherical_intersect/high_level.py +++ b/reproject/spherical_intersect/high_level.py @@ -56,6 +56,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") diff --git a/reproject/spherical_intersect/tests/test_high_level.py b/reproject/spherical_intersect/tests/test_high_level.py new file mode 100644 index 000000000..0bbcfd20d --- /dev/null +++ b/reproject/spherical_intersect/tests/test_high_level.py @@ -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"