diff options
-rw-r--r-- | CHANGES.rst | 3 | ||||
-rw-r--r-- | setup.cfg | 2 | ||||
-rw-r--r-- | stwcs/tests/test_altwcs.py | 3 | ||||
-rw-r--r-- | stwcs/tests/test_headerlet.py | 21 | ||||
-rw-r--r-- | stwcs/tests/test_updatewcs.py | 64 | ||||
-rw-r--r-- | stwcs/updatewcs/apply_corrections.py | 94 |
6 files changed, 134 insertions, 53 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 6b9da19..ef7a82c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,9 @@ - updatewcs() now reads all extension immediately after opening a file to fix a problem after astropy implemented fits lazy loading. [#21] +- Fixed a bug in updating the D2IM correction in a science file when the + a new distortion file was supplied through D2IMFILE keyword. [#22] + 1.2.4 (2016-10-27) ------------------ @@ -8,7 +8,7 @@ license = BSD edit_on_github = False github_project = spacetelescope/stwcs -[pytest] +[tool:pytest] minversion = 2.2 norecursedirs = build docs/_build relic diff --git a/stwcs/tests/test_altwcs.py b/stwcs/tests/test_altwcs.py index d646106..fa7eb9b 100644 --- a/stwcs/tests/test_altwcs.py +++ b/stwcs/tests/test_altwcs.py @@ -117,7 +117,6 @@ class TestAltWCS(object): def test_restore_wcs_from_to(self): # test restore from ... to ... - #altwcs.archiveWCS(self.acs_file, ext=[('SCI',1), ('SCI',2)], wcskey='T') pyfits.setval(self.acs_file, ext=('SCI', 1), keyword='CRVAL1', value=1) pyfits.setval(self.acs_file, ext=('SCI', 2), keyword='CRVAL1', value=1) f = pyfits.open(self.acs_file, mode='update') @@ -140,9 +139,7 @@ class TestAltWCS(object): compare_wcs(w3, w1o, exclude_keywords=['ctype']) def test_delete_wcs(self): - #altwcs.archiveWCS(self.acs_file, ext=1, wcskey='Z') altwcs.deleteWCS(self.acs_file, ext=1, wcskey='Z') - #utils.assert_raises(KeyError, wcsutil.HSTWCS, self.acs_file, ext=1, wcskey='Z') with pytest.raises(KeyError): wcsutil.HSTWCS(self.acs_file, ext=1, wcskey='Z') diff --git a/stwcs/tests/test_headerlet.py b/stwcs/tests/test_headerlet.py index f4fa050..ab250a8 100644 --- a/stwcs/tests/test_headerlet.py +++ b/stwcs/tests/test_headerlet.py @@ -8,7 +8,7 @@ from ..wcsutil import headerlet, wcsdiff from ..wcsutil import HSTWCS import numpy as np from numpy.testing import utils -from nose.tools import * +import pytest from . import data data_path = os.path.split(os.path.abspath(data.__file__))[0] @@ -100,7 +100,6 @@ class TestCreateHeaderlet(object): assert(wcsdiff.is_wcs_identical(self.simple_file, self.headerlet_name, [0], [1], verbose=True)[0]) - @raises(KeyError) def test_no_HDRNAME_no_WCSNAME(self): """ Test create_headerlet stepping through all @@ -108,9 +107,10 @@ class TestCreateHeaderlet(object): """ newf = get_filepath('ncomp.fits', os.path.abspath(os.path.curdir)) shutil.copyfile(self.comp_file, newf) - fits.delval(newf, 'HDRNAME', ext=1) + #fits.delval(newf, 'HDRNAME', ext=1) fits.delval(newf, 'WCSNAME', ext=1) - hlet = headerlet.create_headerlet(newf) + with pytest.raises(KeyError): + hlet = headerlet.create_headerlet(newf) def test1SciExt(self): """ @@ -176,23 +176,24 @@ class TestApplyHeaderlet: hlet.apply_as_primary('comp.fits') """ - @raises(ValueError) + def testWrongSIPModel(self): hlet = headerlet.create_headerlet(self.comp_file, hdrname='test1', sipname='WRONG') - hlet.apply_as_primary(self.comp_file) + with pytest.raises(ValueError): + hlet.apply_as_primary(self.comp_file) - @raises(ValueError) def testWrongNPOLModel(self): hlet = headerlet.create_headerlet(self.comp_file, hdrname='test1', npolfile='WRONG') - hlet.apply_as_primary(self.comp_file) + with pytest.raises(ValueError): + hlet.apply_as_primary(self.comp_file) - @raises(ValueError) def testWrongD2IMModel(self): hlet = headerlet.create_headerlet(self.comp_file, hdrname='test1', d2imfile='WRONG') - hlet.apply_as_primary(self.comp_file) + with pytest.raises(ValueError): + hlet.apply_as_primary(self.comp_file) def test_apply_as_primary_method(self): hlet = headerlet.create_headerlet(self.comp_file, hdrname='test2') diff --git a/stwcs/tests/test_updatewcs.py b/stwcs/tests/test_updatewcs.py index b7e75c8..c4e58db 100644 --- a/stwcs/tests/test_updatewcs.py +++ b/stwcs/tests/test_updatewcs.py @@ -296,12 +296,68 @@ def test_add_radesys(): fits.setval(acs_file, ext=0, keyword="NPOLFILE", value=npol_file) fits.setval(acs_file, ext=0, keyword="D2IMFILE", value=d2imfile) - #shutil.copyfile('orig/ibof01ahq_flt.fits', './ibof01ahq_flt.fits') updatewcs.updatewcs(acs_file) - # updatewcs.updatewcs('ibof01ahq_flt.fits') for ext in [('SCI', 1), ('SCI', 2)]: hdr = fits.getheader(acs_file, ext) assert hdr['RADESYS'] == 'FK5' - #hdr = fits.getheader('ibof01ahq_flt.fits', ext=('SCI', 1)) - #assert hdr['RADESYS'] == 'ICRS' +def test_update_d2im_distortion(): + acs_orig_file = get_filepath('j94f05bgq_flt.fits') + current_dir = os.path.abspath(os.path.curdir) + acs_file = get_filepath('j94f05bgq_flt.fits', current_dir) + + idctab = get_filepath('postsm4_idc.fits') + npol_file = get_filepath('qbu16424j_npl.fits') + d2imfile = get_filepath('new_wfc_d2i.fits') + newd2im = get_filepath('new_wfc_d2i.fits', current_dir) + try: + os.remove(acs_file) + except OSError: + pass + shutil.copyfile(acs_orig_file, acs_file) + fits.setval(acs_file, ext=0, keyword="IDCTAB", value=idctab) + fits.setval(acs_file, ext=0, keyword="NPOLFILE", value=npol_file) + fits.setval(acs_file, ext=0, keyword="D2IMFILE", value=d2imfile) + updatewcs.updatewcs(acs_file) + d2imerr1 = fits.getval(acs_file, ext=1, keyword='D2IMERR1') + d2imerr4 = fits.getval(acs_file, ext=4, keyword='D2IMERR1') + shutil.copyfile(d2imfile, newd2im) + with fits.open(newd2im, mode='update') as newf: + for ext in newf[1:]: + ext.data = ext.data * 100 + + fits.setval(acs_file, keyword="D2IMFILE", value=newd2im) + updatewcs.updatewcs(acs_file) + nd2imerr1 = fits.getval(acs_file, ext=1, keyword='D2IMERR1') + nd2imerr4 = fits.getval(acs_file, ext=4, keyword='D2IMERR1') + assert np.isclose(d2imerr1 * 100, nd2imerr1) + assert np.isclose(d2imerr4 * 100, nd2imerr4) + + +def test_apply_d2im(): + from stwcs.updatewcs import apply_corrections as appc + acs_orig_file = get_filepath('j94f05bgq_flt.fits') + current_dir = os.path.abspath(os.path.curdir) + fname = get_filepath('j94f05bgq_flt.fits', current_dir) + d2imfile = get_filepath('new_wfc_d2i.fits') + try: + os.remove(fname) + except OSError: + pass + shutil.copyfile(acs_orig_file, fname) + fits.setval(fname, ext=0, keyword="D2IMFILE", value=d2imfile) + fits.setval(fname, ext=0, keyword="IDCTAB", value='N/A') + fits.setval(fname, ext=0, keyword="NPOLFILE", value='N/A') + # If D2IMEXT does not exist, the correction should be applied + assert appc.apply_d2im_correction(fname, d2imcorr=True) + updatewcs.updatewcs(fname) + + # Test the case when D2IMFILE == D2IMEXT + assert not appc.apply_d2im_correction(fname, d2imcorr=True) + assert not appc.apply_d2im_correction(fname, d2imcorr=False) + + fits.setval(fname, ext=0, keyword='D2IMFILE', value="N/A") + assert not appc.apply_d2im_correction(fname, d2imcorr=True) + # No D2IMFILE keyword in primary header + fits.delval(fname, ext=0, keyword='D2IMFILE') + assert not appc.apply_d2im_correction(fname, d2imcorr=True) diff --git a/stwcs/updatewcs/apply_corrections.py b/stwcs/updatewcs/apply_corrections.py index 4a8e5ac..247dba0 100644 --- a/stwcs/updatewcs/apply_corrections.py +++ b/stwcs/updatewcs/apply_corrections.py @@ -66,7 +66,7 @@ def setCorrections(fname, vacorr=True, tddcorr=True, npolcorr=True, d2imcorr=Tru if not npolcorr: acorr.remove('NPOLCorr') if 'DET2IMCorr' in acorr: - d2imcorr = applyD2ImCorr(fname, d2imcorr) + d2imcorr = apply_d2im_correction(fname, d2imcorr) if not d2imcorr: acorr.remove('DET2IMCorr') logger.info("Corrections to be applied to {0} {1}".format(fname, acorr)) @@ -158,7 +158,7 @@ def applyNpolCorr(fname, unpolcorr): fnpol0 = fileutil.osfn(fnpol0) if not fileutil.findFile(fnpol0): msg = '"NPOLFILE" exists in primary header but file {0} not found.' - 'Non-polynomial distortion correction will not be applied.'.format(file) + 'Non-polynomial distortion correction will not be applied.'.format(fnpol0) logger.critical(msg) raise IOError("NPOLFILE {0} not found".format(fnpol0)) try: @@ -211,40 +211,64 @@ def isOldStyleDGEO(fname, dgname): return False -def applyD2ImCorr(fname, d2imcorr): +def apply_d2im_correction(fname, d2imcorr): + """ + Logic to decide whether to apply the D2IM correction. + + Parameters + ---------- + fname : str + Science file name. + d2imcorr : bool + Flag indicating if D2IM is should be enabled if allowed. + + Return + ------ + applyD2IMCorr : bool + Flag whether to apply the correction. + + The D2IM correction is applied to a science file if it is in the + allowed corrections for the instrument. The name of the file + with the correction is saved in the ``D2IMFILE`` keyword in the + primary header. When the correction is applied the name of the + file is saved in the ``D2IMEXT`` keyword in the 1st extension header. + + """ applyD2IMCorr = True + if not d2imcorr: + logger.info("D2IM correction not requested - not applying it.") + return False + # get D2IMFILE kw from primary header try: - # get D2IMFILE kw from primary header fd2im0 = fits.getval(fname, 'D2IMFILE') - if fd2im0 == 'N/A': - utils.remove_distortion(fname, "D2IMFILE") - return False - fd2im0 = fileutil.osfn(fd2im0) - if not fileutil.findFile(fd2im0): - msg = """\n\tKw D2IMFILE exists in primary header but file %s not found\n - Detector to image correction will not be applied\n""" % fd2im0 - logger.critical(msg) - print(msg) - raise IOError("D2IMFILE {0} not found".format(fd2im0)) - try: - # get D2IMEXT kw from first extension header - fd2imext = fits.getval(fname, 'D2IMEXT', ext=1) - fd2imext = fileutil.osfn(fd2imext) - if fd2imext and fileutil.findFile(fd2imext): - if fd2im0 != fd2imext: - applyD2IMCorr = True - else: - applyD2IMCorr = False - else: - # D2IM file defined in first extension may not be found - # but if a valid kw exists in the primary header, - # detector to image correction should be applied. - applyD2IMCorr = True - except KeyError: - # the case of D2IMFILE kw present in primary header but D2IMEXT missing - # in first extension header - applyD2IMCorr = True except KeyError: - print('D2IMFILE keyword not found in primary header') - applyD2IMCorr = False - return applyD2IMCorr + logger.info("D2IMFILE keyword is missing - D2IM correction will not be applied.") + return False + if fd2im0 == 'N/A': + utils.remove_distortion(fname, "D2IMFILE") + return False + fd2im0 = fileutil.osfn(fd2im0) + if not fileutil.findFile(fd2im0): + message = "D2IMFILE {0} not found.".format(fname) + logger.critical(message) + raise IOError(message) + try: + # get D2IMEXT kw from first extension header + fd2imext = fits.getval(fname, 'D2IMEXT', ext=1) + + except KeyError: + # the case of D2IMFILE kw present in primary header but D2IMEXT missing + # in first extension header + return True + fd2imext = fileutil.osfn(fd2imext) + if fd2imext and fileutil.findFile(fd2imext): + if fd2im0 != fd2imext: + applyD2IMCorr = True + else: + applyD2IMCorr = False + else: + # D2IM file defined in first extension may not be found + # but if a valid kw exists in the primary header, + # detector to image correction should be applied. + applyD2IMCorr = True + return applyD2IMCorr |