From a4e36d7109041ed1f04bae3e2ca42cb193468857 Mon Sep 17 00:00:00 2001 From: stscicrawford Date: Sun, 28 Jul 2019 16:28:56 -0400 Subject: [PATCH 1/2] added better negative number handling to create_deviation --- CHANGES.rst | 6 ++++++ ccdproc/core.py | 21 ++++++++++++++++++--- ccdproc/tests/test_ccdproc.py | 26 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 5c691017..af2e393f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -13,6 +13,9 @@ New Features - Add option to use regular expression matching when filtering items in ``ImageFileCollection``. [#480, #595, #682] +- Added an option to disregard negative values passed to ``create_deviation`` + and assume the error is represented by the read noise [#688] + Other Changes and Additions ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,6 +37,9 @@ Other Changes and Additions - 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] +- Improved warning for negative values in the array passed to + ``create_deviation`` [#688] + - Removed support for initializing ``ImageFileCollection`` from a table instead of files. [#680] diff --git a/ccdproc/core.py b/ccdproc/core.py index bbcdbf7b..5b711548 100644 --- a/ccdproc/core.py +++ b/ccdproc/core.py @@ -273,7 +273,7 @@ def ccd_process(ccd, oscan=None, trim=None, error=False, master_bias=None, @log_to_metadata -def create_deviation(ccd_data, gain=None, readnoise=None): +def create_deviation(ccd_data, gain=None, readnoise=None, disregard_nan=False): """ Create a uncertainty frame. The function will update the uncertainty plane which gives the standard deviation for the data. Gain is used in @@ -296,6 +296,10 @@ def create_deviation(ccd_data, gain=None, readnoise=None): Read noise per pixel. Default is ``None``. + disregard_nan: boolean + If ``True``, any value of nan in the output array will be replaced by + the readnoise. + {log} Raises @@ -331,9 +335,20 @@ def create_deviation(ccd_data, gain=None, readnoise=None): gain_value = float(gain / gain.unit) readnoise_value = float(readnoise / readnoise.unit) - var = (gain_value * ccd_data.data + readnoise_value ** 2) ** 0.5 - ccd = ccd_data.copy() + # remove values that might be negative or treat as nan + data = gain_value * ccd_data.data + mask = (data < 0) + if disregard_nan: + data[mask] = 0 + else: + data[mask] = np.nan + logging.warning('Negative values in array will be replaced with nan') + + # calculate the deviation + var = (data + readnoise_value ** 2) ** 0.5 + # ensure uncertainty and image data have same unit + ccd = ccd_data.copy() var /= gain_value ccd.uncertainty = StdDevUncertainty(var) return ccd diff --git a/ccdproc/tests/test_ccdproc.py b/ccdproc/tests/test_ccdproc.py index 481ce797..26df786a 100644 --- a/ccdproc/tests/test_ccdproc.py +++ b/ccdproc/tests/test_ccdproc.py @@ -41,6 +41,7 @@ (u.adu, u.photon / u.adu, u.electron, False), ]) @pytest.mark.data_size(10) +@pytest.mark.data_mean(100) def test_create_deviation(ccd_data, u_image, u_gain, u_readnoise, expect_success): ccd_data.unit = u_image @@ -69,6 +70,31 @@ def test_create_deviation(ccd_data, u_image, u_gain, u_readnoise, ccd_var = create_deviation(ccd_data, gain=gain, readnoise=readnoise) +@pytest.mark.data_mean(0) +@pytest.mark.data_scale(10) +def test_create_deviation_from_negative(ccd_data): + ccd_data.unit = u.electron + readnoise = 5 * u.electron + ccd_var = create_deviation(ccd_data, gain=None, readnoise=readnoise, + disregard_nan=False) + np.testing.assert_array_equal(ccd_data.data < 0, + np.isnan(ccd_var.uncertainty.array)) + + +@pytest.mark.data_mean(0) +@pytest.mark.data_scale(10) +def test_create_deviation_from_negative(ccd_data): + ccd_data.unit = u.electron + readnoise = 5 * u.electron + ccd_var = create_deviation(ccd_data, gain=None, readnoise=readnoise, + disregard_nan=True) + mask = (ccd_data.data < 0) + ccd_data.data[mask] = 0 + expected_var = np.sqrt(ccd_data.data + readnoise.value**2) + np.testing.assert_array_equal(ccd_var.uncertainty.array, + expected_var) + + def test_create_deviation_keywords_must_have_unit(ccd_data): # gain must have units if provided with pytest.raises(TypeError): From 28ba7fe9eeb4a4a04572b7e448086f3f03f41488 Mon Sep 17 00:00:00 2001 From: stscicrawford Date: Sun, 28 Jul 2019 20:46:34 -0400 Subject: [PATCH 2/2] fix pep8 --- ccdproc/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ccdproc/core.py b/ccdproc/core.py index 5b711548..e12515fa 100644 --- a/ccdproc/core.py +++ b/ccdproc/core.py @@ -339,10 +339,10 @@ def create_deviation(ccd_data, gain=None, readnoise=None, disregard_nan=False): data = gain_value * ccd_data.data mask = (data < 0) if disregard_nan: - data[mask] = 0 + data[mask] = 0 else: - data[mask] = np.nan - logging.warning('Negative values in array will be replaced with nan') + data[mask] = np.nan + logging.warning('Negative values in array will be replaced with nan') # calculate the deviation var = (data + readnoise_value ** 2) ** 0.5