From caab902f20648009a2b5c186ba05d2e8f6d48847 Mon Sep 17 00:00:00 2001 From: Robel Geda Date: Wed, 16 May 2018 14:54:00 -0400 Subject: [PATCH 01/10] HDU Header for components --- glue/core/data_exporters/gridded_fits.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/glue/core/data_exporters/gridded_fits.py b/glue/core/data_exporters/gridded_fits.py index 0bed34146..f370a1843 100644 --- a/glue/core/data_exporters/gridded_fits.py +++ b/glue/core/data_exporters/gridded_fits.py @@ -9,6 +9,11 @@ __all__ = [] +def make_component_header(component, data_header): + header = data_header + header["BUNIT"] = component.units + return header + @data_exporter(label='FITS (1 component/HDU)', extension=['fits', 'fit']) def fits_writer(filename, data, components=None): """ @@ -28,6 +33,8 @@ def fits_writer(filename, data, components=None): else: mask = None + data_header = data.coords.header if hasattr(data.coords, "header") else None + from astropy.io import fits hdus = fits.HDUList() @@ -50,7 +57,8 @@ def fits_writer(filename, data, components=None): values[~mask] = np.nan # TODO: special behavior for PRIMARY? - hdu = fits.ImageHDU(values, name=cid.label) + header = make_component_header(comp, data_header) if data_header else None + hdu = fits.ImageHDU(values, name=cid.label, header=header) hdus.append(hdu) try: From 6b0dec3d9c3ed21ce973ac3f3d32df1e1a021c32 Mon Sep 17 00:00:00 2001 From: Robel Geda Date: Wed, 16 May 2018 15:05:23 -0400 Subject: [PATCH 02/10] Comments --- glue/core/data_exporters/gridded_fits.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/glue/core/data_exporters/gridded_fits.py b/glue/core/data_exporters/gridded_fits.py index f370a1843..490c62700 100644 --- a/glue/core/data_exporters/gridded_fits.py +++ b/glue/core/data_exporters/gridded_fits.py @@ -9,9 +9,19 @@ __all__ = [] -def make_component_header(component, data_header): - header = data_header +def make_component_header(component, header): + """ + Function that extracts information from components + and adds it to the data header. The input header is + expected to come from Data.coords.header by default. + :param component: glue Component + :param header: astropy.io.fits.header.Header + :return: + """ + + # Add units information header["BUNIT"] = component.units + return header @data_exporter(label='FITS (1 component/HDU)', extension=['fits', 'fit']) From fe8c245ed3fb594b2f321cfd52a6620b747a4f04 Mon Sep 17 00:00:00 2001 From: Robel Geda Date: Wed, 16 May 2018 15:29:19 -0400 Subject: [PATCH 03/10] Units in fits factories --- glue/core/data_factories/deprecated.py | 4 +++- glue/core/data_factories/fits.py | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/glue/core/data_factories/deprecated.py b/glue/core/data_factories/deprecated.py index c6c865deb..4aa2f4a34 100644 --- a/glue/core/data_factories/deprecated.py +++ b/glue/core/data_factories/deprecated.py @@ -134,14 +134,16 @@ def gridded_data(filename, format='auto', **kwargs): from astropy.io import fits arrays = extract_data_fits(filename, **kwargs) header = fits.getheader(filename) + u = header["BUNIT"] if "BUNIT" in header else None result.coords = coordinates_from_header(header) elif is_hdf5(filename): + u = None arrays = extract_data_hdf5(filename, **kwargs) else: raise Exception("Unkonwn format: %s" % format) for component_name in arrays: - comp = Component.autotyped(arrays[component_name]) + comp = Component.autotyped(arrays[component_name], units=u) result.add_component(comp, component_name) return result diff --git a/glue/core/data_factories/fits.py b/glue/core/data_factories/fits.py index 1d06b8f74..31e939673 100644 --- a/glue/core/data_factories/fits.py +++ b/glue/core/data_factories/fits.py @@ -114,6 +114,7 @@ def new_data(suffix=True): if is_image_hdu(hdu): shape = hdu.data.shape coords = coordinates_from_header(hdu.header) + u = hdu.header["BUNIT"] if "BUNIT" in hdu.header else None if not auto_merge or has_wcs(coords): data = new_data(suffix=len(hdulist) > 1) else: @@ -121,7 +122,8 @@ def new_data(suffix=True): data = groups[extension_by_shape[shape]] except KeyError: data = new_data(suffix=len(hdulist) > 1) - data.add_component(component=hdu.data, + component = Component.autotyped(hdu.data, units=u) + data.add_component(component=component, label=hdu_name) elif is_table_hdu(hdu): # Loop through columns and make component list @@ -205,7 +207,9 @@ def casalike_cube(filename, **kwargs): header = hdulist[0].header result.coords = coordinates_from_header(header) for i in range(array.shape[0]): - result.add_component(array[[i]], label='STOKES %i' % i) + u = header["BUNIT"] if "BUNIT" in header else None + component = Component.autotyped(array[[i]], units=u) + result.add_component(component, label='STOKES %i' % i) return result From 42e681fc930b7f6364076ea61cc2e49519835e1f Mon Sep 17 00:00:00 2001 From: Robel Geda Date: Wed, 16 May 2018 15:33:23 -0400 Subject: [PATCH 04/10] Rename unit var --- glue/core/data_factories/deprecated.py | 4 +--- glue/core/data_factories/fits.py | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/glue/core/data_factories/deprecated.py b/glue/core/data_factories/deprecated.py index 4aa2f4a34..c6c865deb 100644 --- a/glue/core/data_factories/deprecated.py +++ b/glue/core/data_factories/deprecated.py @@ -134,16 +134,14 @@ def gridded_data(filename, format='auto', **kwargs): from astropy.io import fits arrays = extract_data_fits(filename, **kwargs) header = fits.getheader(filename) - u = header["BUNIT"] if "BUNIT" in header else None result.coords = coordinates_from_header(header) elif is_hdf5(filename): - u = None arrays = extract_data_hdf5(filename, **kwargs) else: raise Exception("Unkonwn format: %s" % format) for component_name in arrays: - comp = Component.autotyped(arrays[component_name], units=u) + comp = Component.autotyped(arrays[component_name]) result.add_component(comp, component_name) return result diff --git a/glue/core/data_factories/fits.py b/glue/core/data_factories/fits.py index 31e939673..7f67bb259 100644 --- a/glue/core/data_factories/fits.py +++ b/glue/core/data_factories/fits.py @@ -114,7 +114,7 @@ def new_data(suffix=True): if is_image_hdu(hdu): shape = hdu.data.shape coords = coordinates_from_header(hdu.header) - u = hdu.header["BUNIT"] if "BUNIT" in hdu.header else None + units = hdu.header["BUNIT"] if "BUNIT" in hdu.header else None if not auto_merge or has_wcs(coords): data = new_data(suffix=len(hdulist) > 1) else: @@ -122,7 +122,7 @@ def new_data(suffix=True): data = groups[extension_by_shape[shape]] except KeyError: data = new_data(suffix=len(hdulist) > 1) - component = Component.autotyped(hdu.data, units=u) + component = Component.autotyped(hdu.data, units=units) data.add_component(component=component, label=hdu_name) elif is_table_hdu(hdu): @@ -207,8 +207,8 @@ def casalike_cube(filename, **kwargs): header = hdulist[0].header result.coords = coordinates_from_header(header) for i in range(array.shape[0]): - u = header["BUNIT"] if "BUNIT" in header else None - component = Component.autotyped(array[[i]], units=u) + units = header["BUNIT"] if "BUNIT" in header else None + component = Component.autotyped(array[[i]], units=units) result.add_component(component, label='STOKES %i' % i) return result From f27253ea938c81df9b85bf2309da1e49e98bd359 Mon Sep 17 00:00:00 2001 From: Robel Geda Date: Wed, 16 May 2018 15:36:09 -0400 Subject: [PATCH 05/10] Fix flake8 --- glue/core/data_exporters/gridded_fits.py | 1 + 1 file changed, 1 insertion(+) diff --git a/glue/core/data_exporters/gridded_fits.py b/glue/core/data_exporters/gridded_fits.py index 490c62700..4d5759b18 100644 --- a/glue/core/data_exporters/gridded_fits.py +++ b/glue/core/data_exporters/gridded_fits.py @@ -24,6 +24,7 @@ def make_component_header(component, header): return header + @data_exporter(label='FITS (1 component/HDU)', extension=['fits', 'fit']) def fits_writer(filename, data, components=None): """ From be1e8cf2317798836b2894aaaa0d4d24077795f7 Mon Sep 17 00:00:00 2001 From: Robel Geda Date: Thu, 17 May 2018 13:36:59 -0400 Subject: [PATCH 06/10] Small fixes --- glue/core/data_exporters/gridded_fits.py | 14 +++++++++----- glue/core/data_factories/fits.py | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/glue/core/data_exporters/gridded_fits.py b/glue/core/data_exporters/gridded_fits.py index 4d5759b18..deb7184ad 100644 --- a/glue/core/data_exporters/gridded_fits.py +++ b/glue/core/data_exporters/gridded_fits.py @@ -4,7 +4,7 @@ from glue.core import Subset from glue.config import data_exporter - +from glue.core.coordinates import WCSCoordinates __all__ = [] @@ -14,9 +14,13 @@ def make_component_header(component, header): Function that extracts information from components and adds it to the data header. The input header is expected to come from Data.coords.header by default. - :param component: glue Component - :param header: astropy.io.fits.header.Header - :return: + Parameters + ---------- + component: glue Component + Glue component to extract info from + header: astropy.io.fits.header.Header + Input header to be modified according to + the input component """ # Add units information @@ -44,7 +48,7 @@ def fits_writer(filename, data, components=None): else: mask = None - data_header = data.coords.header if hasattr(data.coords, "header") else None + data_header = data.coords.header if isinstance(data.coords, WCSCoordinates) else None from astropy.io import fits diff --git a/glue/core/data_factories/fits.py b/glue/core/data_factories/fits.py index 7f67bb259..a200ac34b 100644 --- a/glue/core/data_factories/fits.py +++ b/glue/core/data_factories/fits.py @@ -114,7 +114,7 @@ def new_data(suffix=True): if is_image_hdu(hdu): shape = hdu.data.shape coords = coordinates_from_header(hdu.header) - units = hdu.header["BUNIT"] if "BUNIT" in hdu.header else None + units = hdu.header.get('BUNIT')if "BUNIT" in hdu.header else None if not auto_merge or has_wcs(coords): data = new_data(suffix=len(hdulist) > 1) else: @@ -207,7 +207,7 @@ def casalike_cube(filename, **kwargs): header = hdulist[0].header result.coords = coordinates_from_header(header) for i in range(array.shape[0]): - units = header["BUNIT"] if "BUNIT" in header else None + units = hdu.header.get('BUNIT') if "BUNIT" in header else None component = Component.autotyped(array[[i]], units=units) result.add_component(component, label='STOKES %i' % i) return result From 5e606b5ea4e1ff37a51aaea15c54a85aa42d038f Mon Sep 17 00:00:00 2001 From: Robel Geda Date: Thu, 17 May 2018 13:48:56 -0400 Subject: [PATCH 07/10] fix travis --- glue/core/data_factories/fits.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue/core/data_factories/fits.py b/glue/core/data_factories/fits.py index a200ac34b..088d3ca82 100644 --- a/glue/core/data_factories/fits.py +++ b/glue/core/data_factories/fits.py @@ -207,7 +207,7 @@ def casalike_cube(filename, **kwargs): header = hdulist[0].header result.coords = coordinates_from_header(header) for i in range(array.shape[0]): - units = hdu.header.get('BUNIT') if "BUNIT" in header else None + units = header.get('BUNIT') if "BUNIT" in header else None component = Component.autotyped(array[[i]], units=units) result.add_component(component, label='STOKES %i' % i) return result From 4cb2b2948df2e65bde79d0ac52c22a6caced111e Mon Sep 17 00:00:00 2001 From: Robel Geda Date: Fri, 18 May 2018 14:13:53 -0400 Subject: [PATCH 08/10] Fix get --- glue/core/data_factories/fits.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glue/core/data_factories/fits.py b/glue/core/data_factories/fits.py index 088d3ca82..5b7aa6292 100644 --- a/glue/core/data_factories/fits.py +++ b/glue/core/data_factories/fits.py @@ -114,7 +114,7 @@ def new_data(suffix=True): if is_image_hdu(hdu): shape = hdu.data.shape coords = coordinates_from_header(hdu.header) - units = hdu.header.get('BUNIT')if "BUNIT" in hdu.header else None + units = hdu.header.get('BUNIT') if not auto_merge or has_wcs(coords): data = new_data(suffix=len(hdulist) > 1) else: @@ -207,7 +207,7 @@ def casalike_cube(filename, **kwargs): header = hdulist[0].header result.coords = coordinates_from_header(header) for i in range(array.shape[0]): - units = header.get('BUNIT') if "BUNIT" in header else None + units = header.get('BUNIT') component = Component.autotyped(array[[i]], units=units) result.add_component(component, label='STOKES %i' % i) return result From 1e2fa8efaa62758bec72fc51e178743cd614412f Mon Sep 17 00:00:00 2001 From: Robel Geda Date: Fri, 18 May 2018 17:06:54 -0400 Subject: [PATCH 09/10] Tests --- .../data_exporters/tests/test_gridded_fits.py | 31 ++++++++++++++++++ .../core/data_factories/tests/data/bunit.fits | Bin 0 -> 5760 bytes glue/core/data_factories/tests/test_fits.py | 10 ++++++ 3 files changed, 41 insertions(+) create mode 100644 glue/core/data_factories/tests/data/bunit.fits diff --git a/glue/core/data_exporters/tests/test_gridded_fits.py b/glue/core/data_exporters/tests/test_gridded_fits.py index c60fd5a39..7a6c0dcbb 100644 --- a/glue/core/data_exporters/tests/test_gridded_fits.py +++ b/glue/core/data_exporters/tests/test_gridded_fits.py @@ -2,7 +2,9 @@ import numpy as np from glue.core import Data +from glue.core.coordinates import WCSCoordinates from astropy.io import fits +from astropy.wcs import WCS from ..gridded_fits import fits_writer @@ -32,6 +34,35 @@ def test_fits_writer_data(tmpdir): np.testing.assert_equal(hdulist['x'].data, data['x']) +def test_component_unit_header(tmpdir): + from astropy import units as u + filename = tmpdir.join('test3.fits').strpath + + data = Data(x=np.arange(6).reshape(2, 3), + y=(np.arange(6) * 2).reshape(2, 3), + z=(np.arange(6) * 2).reshape(2, 3)) + + wcs = WCS() + data.coords = WCSCoordinates(wcs=wcs) + + unit1 = data.get_component("x").units = u.m/u.s + unit2 = data.get_component("y").units = u.Jy + unit3 = data.get_component("z").units = "" + + fits_writer(filename, data) + + with fits.open(filename) as hdulist: + assert len(hdulist) == 3 + bunit = hdulist['x'].header.get('BUNIT') + assert u.Unit(bunit) == unit1 + + bunit = hdulist['y'].header.get('BUNIT') + assert u.Unit(bunit) == unit2 + + bunit = hdulist['z'].header.get('BUNIT') + assert bunit == unit3 + + def test_fits_writer_subset(tmpdir): filename = tmpdir.join('test').strpath diff --git a/glue/core/data_factories/tests/data/bunit.fits b/glue/core/data_factories/tests/data/bunit.fits new file mode 100644 index 0000000000000000000000000000000000000000..bfea37ce76414141bfe4f142b532ccc6e4bb4332 GIT binary patch literal 5760 zcmeH@u};G<5QZ5U85kHCP6$zifHnoOA=(NfxuT|0jFi=oRO%2LB}O7|%_Cr%L(O2R z85w>L`R=UqugjOp#qwDY-BaXf8q&M7D_4~@c}GuDr&N1mb5rG!`EWIpdMUGL-qqc0 z$TL-C8p@3~3X-{3`w$KO|j&eI_kU%uUktSNW?F3nz*)FB|`&6_r;o7ai%R|>V+soyZB zU;qYS00v+H24DaNb{g2@^YGmk6YeMb+#fIxnMcfHCNWQ#r_3|vIrD;f$-HKcm Date: Fri, 18 May 2018 17:26:53 -0400 Subject: [PATCH 10/10] Fix white space --- glue/core/data_exporters/tests/test_gridded_fits.py | 2 +- glue/core/data_factories/tests/test_fits.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/glue/core/data_exporters/tests/test_gridded_fits.py b/glue/core/data_exporters/tests/test_gridded_fits.py index 7a6c0dcbb..f7b2e9b36 100644 --- a/glue/core/data_exporters/tests/test_gridded_fits.py +++ b/glue/core/data_exporters/tests/test_gridded_fits.py @@ -45,7 +45,7 @@ def test_component_unit_header(tmpdir): wcs = WCS() data.coords = WCSCoordinates(wcs=wcs) - unit1 = data.get_component("x").units = u.m/u.s + unit1 = data.get_component("x").units = u.m / u.s unit2 = data.get_component("y").units = u.Jy unit3 = data.get_component("z").units = "" diff --git a/glue/core/data_factories/tests/test_fits.py b/glue/core/data_factories/tests/test_fits.py index 2146f0481..5c42b233c 100644 --- a/glue/core/data_factories/tests/test_fits.py +++ b/glue/core/data_factories/tests/test_fits.py @@ -27,6 +27,7 @@ def _assert_equal_expected(actual, expected): assert e.shape == d.shape assert e.ndim == d.ndim + @requires_astropy def test_component_unit(): from astropy import units as u