From 686814f2265fc287985c8c27d0b59ac4e7a34ede Mon Sep 17 00:00:00 2001 From: stscicrawford Date: Sun, 28 Jul 2019 12:30:46 -0400 Subject: [PATCH 1/4] added warning to transform_image that it does not apply to WCS --- CHANGES.rst | 3 +++ ccdproc/core.py | 13 ++++++++++--- ccdproc/tests/test_ccdproc.py | 9 +++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 864425a2..61d33318 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -19,6 +19,9 @@ Other Changes and Additions - Added support for .bz2, .Z and .zip file formats in ``ImageFileCollection``. +- Added warning that ``transform_image`` does not apply the transformation to the WCS [#684] + + Bug Fixes ^^^^^^^^^ - Function ``median_combine`` now correctly calculates the uncertainty for diff --git a/ccdproc/core.py b/ccdproc/core.py index 13da2d84..e95b9a86 100644 --- a/ccdproc/core.py +++ b/ccdproc/core.py @@ -2,10 +2,13 @@ """This module implements the base CCDPROC functions""" +import math import numbers +import logging import numpy as np -import math +from scipy import ndimage + from astropy.units.quantity import Quantity from astropy import units as u from astropy.modeling import fitting @@ -16,12 +19,12 @@ from astropy.utils import deprecated import astropy # To get the version. -from scipy import ndimage - from .utils.slices import slice_from_string from .log_meta import log_to_metadata from .extern.bitfield import bitfield_to_boolean_mask as _bitfield_to_boolean_mask +logger = logging.getLogger(__name__) + __all__ = ['background_deviation_box', 'background_deviation_filter', 'ccd_process', 'cosmicray_median', 'cosmicray_lacosmic', 'create_deviation', 'flat_correct', 'gain_correct', 'rebin', @@ -853,6 +856,10 @@ def transform_image(ccd, transform_func, **kwargs): mask = transform_func(nccd.mask, **kwargs) nccd.mask = mask > 0 + if nccd.wcs is not None: + warn = 'WCS information may be incorrect as no transformation was applied to it' + logging.warning(warn) + return nccd diff --git a/ccdproc/tests/test_ccdproc.py b/ccdproc/tests/test_ccdproc.py index f61c2be5..bfe96bdd 100644 --- a/ccdproc/tests/test_ccdproc.py +++ b/ccdproc/tests/test_ccdproc.py @@ -573,6 +573,15 @@ def test_transform_isfunc(ccd_data): with pytest.raises(TypeError): transform_image(ccd_data, 1) +#test warning is issue if WCS information is available +def test_catch_transform_wcs_warning(ccd_data): + + def tran(arr): + return 10 * arr + + with catch_warnings() as w: + tran = transform_image(ccd_data, tran) + @pytest.mark.parametrize('mask_data, uncertainty', [ (False, False), From 8f79122d2fd572e8a21978411508c3b0998b511e Mon Sep 17 00:00:00 2001 From: stscicrawford Date: Sun, 28 Jul 2019 14:44:44 -0400 Subject: [PATCH 2/4] remove existing wcs header keywords if wcs_project is run --- ccdproc/core.py | 7 ++++- ccdproc/tests/test_ccdproc.py | 53 +++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/ccdproc/core.py b/ccdproc/core.py index a13cf650..898b7cfe 100644 --- a/ccdproc/core.py +++ b/ccdproc/core.py @@ -902,6 +902,7 @@ def wcs_project(ccd, target_wcs, target_shape=None, order='bilinear'): ccd : `~astropy.nddata.CCDData` A transformed CCDData object. """ + from astropy.nddata.ccddata import _generate_wcs_and_update_header from reproject import reproject_interp if not (ccd.wcs.is_celestial and target_wcs.is_celestial): @@ -941,9 +942,13 @@ def wcs_project(ccd, target_wcs, target_shape=None, order='bilinear'): if not output_mask.any(): output_mask = None + # If there are any wcs keywords in the header, remove them + hdr, _ = _generate_wcs_and_update_header(ccd.header) + print(hdr) + nccd = CCDData(area_ratio * projected_image_raw, wcs=target_wcs, mask=output_mask, - header=ccd.header, unit=ccd.unit) + header=hdr, unit=ccd.unit) return nccd diff --git a/ccdproc/tests/test_ccdproc.py b/ccdproc/tests/test_ccdproc.py index bfe96bdd..481ce797 100644 --- a/ccdproc/tests/test_ccdproc.py +++ b/ccdproc/tests/test_ccdproc.py @@ -432,6 +432,7 @@ def test_unit_mismatch_behaves_as_expected(ccd_data): # Was the error message as expected? assert expected_message in str(e.value) + # test for flat correction @pytest.mark.data_scale(10) def test_flat_correct(ccd_data): @@ -443,7 +444,7 @@ def test_flat_correct(ccd_data): flat = CCDData(data, meta=fits.header.Header(), unit=ccd_data.unit) flat_data = flat_correct(ccd_data, flat, add_keyword=None) - #check that the flat was normalized + # check that the flat was normalized # Should be the case that flat * flat_data = ccd_data * flat.data.mean # if the normalization was done correctly. np.testing.assert_almost_equal((flat_data.data * flat.data).mean(), @@ -545,6 +546,7 @@ def test_flat_correct_data_uncertainty(): assert (res.data == dat.data).all() assert (res.uncertainty.array == dat.uncertainty.array).all() + # tests for gain correction def test_gain_correct(ccd_data): init_data = ccd_data.data @@ -562,25 +564,26 @@ def test_gain_correct_quantity(ccd_data): assert ccd_data.unit == u.electron -#test transform is ccd +# test transform is ccd def test_transform_isccd(): with pytest.raises(TypeError): transform_image(1, 1) -#test function is callable +# test function is callable def test_transform_isfunc(ccd_data): with pytest.raises(TypeError): transform_image(ccd_data, 1) -#test warning is issue if WCS information is available + +# test warning is issue if WCS information is available def test_catch_transform_wcs_warning(ccd_data): def tran(arr): return 10 * arr with catch_warnings() as w: - tran = transform_image(ccd_data, tran) + tran = transform_image(ccd_data, tran) @pytest.mark.parametrize('mask_data, uncertainty', [ @@ -700,20 +703,20 @@ def test_block_replicate(): assert 'testkw2' not in ccd.meta -#test blockaveraging ndarray +# test blockaveraging ndarray def test__blkavg_ndarray(): with pytest.raises(TypeError): _blkavg(1, (5, 5)) -#test rebinning dimensions +# test rebinning dimensions @pytest.mark.data_size(10) def test__blkavg_dimensions(ccd_data): with pytest.raises(ValueError): _blkavg(ccd_data.data, (5,)) -#test blkavg works +# test blkavg works @pytest.mark.data_size(20) def test__blkavg_larger(ccd_data): a = ccd_data.data @@ -723,10 +726,10 @@ def test__blkavg_larger(ccd_data): np.testing.assert_almost_equal(b.sum(), 0.25 * a.sum()) -#test overscan changes +# test overscan changes def test__overscan_schange(ccd_data): old_data = ccd_data.copy() - new_data = subtract_overscan(ccd_data, overscan=ccd_data[:,1], overscan_axis=0) + new_data = subtract_overscan(ccd_data, overscan=ccd_data[:, 1], overscan_axis=0) assert not np.allclose(old_data.data, new_data.data) np.testing.assert_array_equal(old_data.data, ccd_data.data) @@ -737,13 +740,15 @@ def test_create_deviation_does_not_change_input(ccd_data): np.testing.assert_array_equal(original.data, ccd_data.data) assert original.unit == ccd_data.unit + def test_cosmicray_median_does_not_change_input(ccd_data): original = ccd_data.copy() error = np.zeros_like(ccd_data) - ccd = cosmicray_median(ccd_data,error_image=error, thresh=5, mbox=11, gbox=0, rbox=0) - np.testing.assert_array_equal(original.data,ccd_data.data) + ccd = cosmicray_median(ccd_data, error_image=error, thresh=5, mbox=11, gbox=0, rbox=0) + np.testing.assert_array_equal(original.data, ccd_data.data) assert original.unit == ccd_data.unit + def test_cosmicray_lacosmic_does_not_change_input(ccd_data): original = ccd_data.copy() error = np.zeros_like(ccd_data) @@ -751,19 +756,22 @@ def test_cosmicray_lacosmic_does_not_change_input(ccd_data): np.testing.assert_array_equal(original.data, ccd_data.data) assert original.unit == ccd_data.unit + def test_flat_correct_does_not_change_input(ccd_data): original = ccd_data.copy() flat = CCDData(np.zeros_like(ccd_data), unit=ccd_data.unit) - ccd = flat_correct(ccd_data,flat=flat) + ccd = flat_correct(ccd_data, flat=flat) np.testing.assert_array_equal(original.data, ccd_data.data) assert original.unit == ccd_data.unit + def test_gain_correct_does_not_change_input(ccd_data): original = ccd_data.copy() ccd = gain_correct(ccd_data, gain=1, gain_unit=ccd_data.unit) np.testing.assert_array_equal(original.data, ccd_data.data) assert original.unit == ccd_data.unit + def test_subtract_bias_does_not_change_input(ccd_data): original = ccd_data.copy() master_frame = CCDData(np.zeros_like(ccd_data), unit=ccd_data.unit) @@ -771,6 +779,7 @@ def test_subtract_bias_does_not_change_input(ccd_data): np.testing.assert_array_equal(original.data, ccd_data.data) assert original.unit == ccd_data.unit + def test_trim_image_does_not_change_input(ccd_data): original = ccd_data.copy() ccd = trim_image(ccd_data, fits_section=None) @@ -818,6 +827,19 @@ def test_wcs_project_onto_same_wcs(ccd_data): np.testing.assert_allclose(ccd_data.data, new_ccd.data, rtol=1e-5) +def test_wcs_project_onto_same_wcs_remove_headers(ccd_data): + # Remove an example WCS keyword from the header + target_wcs = wcs_for_testing(ccd_data.shape) + ccd_data.wcs = wcs_for_testing(ccd_data.shape) + print(ccd_data.header) + ccd_data.header = ccd_data.wcs.to_header() + + new_ccd = wcs_project(ccd_data, target_wcs) + + for k in ccd_data.wcs.to_header(): + assert k not in new_ccd.header + + def test_wcs_project_onto_shifted_wcs(ccd_data): # Just make the target WCS the same as the initial with the center # pixel shifted by 1 in x and y. @@ -983,12 +1005,13 @@ def test_ccd_process(): np.testing.assert_array_equal(2.0 * np.ones((100, 90)), occd.data) np.testing.assert_almost_equal(3.0 * np.ones((100, 90)), - occd.uncertainty.array) + occd.uncertainty.array) np.testing.assert_array_equal(mask, occd.mask) assert(occd.unit == u.electron) # Make sure the original keyword is still present. Regression test for #401 assert occd.meta['testkw'] == 100 + def test_ccd_process_gain_corrected(): # test the through ccd_process with gain_corrected as False ccd_data = CCDData(10.0 * np.ones((100, 100)), unit=u.adu) @@ -1019,7 +1042,7 @@ def test_ccd_process_gain_corrected(): np.testing.assert_array_equal(2.0 * np.ones((100, 90)), occd.data) np.testing.assert_almost_equal(3.0 * np.ones((100, 90)), - occd.uncertainty.array) + occd.uncertainty.array) np.testing.assert_array_equal(mask, occd.mask) assert(occd.unit == u.electron) # Make sure the original keyword is still present. Regression test for #401 From 2c889759c5715d3fb775612f41b0f79c931731b1 Mon Sep 17 00:00:00 2001 From: stscicrawford Date: Sun, 28 Jul 2019 14:57:48 -0400 Subject: [PATCH 3/4] Update to the change log --- CHANGES.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0fdc212c..5c691017 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -28,7 +28,11 @@ Other Changes and Additions - Added support for .bz2, .Z and .zip file formats in ``ImageFileCollection``. -- Added warning that ``transform_image`` does not apply the transformation to the WCS [#684] +- Added warning that ``transform_image`` does not apply the transformation to + the WCS [#684] + +- When creating a new object in ``wcs_transform``, WCS keywords in the header + are removed so that they are only stored in the WCS object [#685] - Removed support for initializing ``ImageFileCollection`` from a table instead of files. [#680] From 983bcf673d58e64b317bf504902bc0c5f3eb3068 Mon Sep 17 00:00:00 2001 From: stscicrawford Date: Sun, 28 Jul 2019 15:05:34 -0400 Subject: [PATCH 4/4] remove print statement --- ccdproc/core.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ccdproc/core.py b/ccdproc/core.py index 898b7cfe..bbcdbf7b 100644 --- a/ccdproc/core.py +++ b/ccdproc/core.py @@ -944,7 +944,6 @@ def wcs_project(ccd, target_wcs, target_shape=None, order='bilinear'): # If there are any wcs keywords in the header, remove them hdr, _ = _generate_wcs_and_update_header(ccd.header) - print(hdr) nccd = CCDData(area_ratio * projected_image_raw, wcs=target_wcs, mask=output_mask,