Skip to content

Commit

Permalink
Don't assume arcseconds when CUNIT metadata isn't present
Browse files Browse the repository at this point in the history
Raise a more sensible Attribute error if CUNIT metadata not present

Fix mapbase tests

Only set LASCO cunit if present

Fix maps doctests

Add changelog

Fix map_from_numpy_array

Fix maps_example

Add clearer error message when unit meatadata not present

Assume arcseconds for EIT maps

Update error message

Move cunit check to _validate_metadata

Revert change to LASCOmap
  • Loading branch information
dstansby committed Mar 7, 2019
1 parent 05c92fc commit 5254f9c
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 8 deletions.
2 changes: 2 additions & 0 deletions changelog/2847.breaking.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Maps no longer assume that the pixel units are arcseconds if the units aren't
explicitly set.
2 changes: 1 addition & 1 deletion docs/guide/data_types/maps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ given then some default values are assumed. Here is a simple example::
>>> import numpy as np

>>> data = np.arange(0,100).reshape(10,10)
>>> header = {'cdelt1': 10, 'cdelt2': 10, 'telescop':'sunpy'}
>>> header = {'cdelt1': 10, 'cdelt2': 10, 'telescop':'sunpy', 'cunit1': 'arcsec', 'cunit2': 'arcsec'}
>>> my_map = sunpy.map.Map(data, header)

The keys in the header follows the `FITS standard <https://fits.gsfc.nasa.gov/fits_dictionary.html>`_.
Expand Down
2 changes: 1 addition & 1 deletion examples/map/map_from_numpy_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# SunPy Maps store 2D data in a numpy array and additional data in a metadata
# dictionary giving information relating to the data and instrument.
data = np.random.rand(20,15)
header = {}
header = {'cunit1': 'arcsec', 'cunit2': 'arcsec'}
manual_map = sunpy.map.Map((data, header))

##############################################################################
Expand Down
2 changes: 1 addition & 1 deletion examples/map/maps_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# Or using creating manually by using tuple with the data/header within:

data = np.random.rand(20, 15)
header = {}
header = {'cunit1': 'arcsec', 'cunit2': 'arcsec'}
manual_map = sunpy.map.Map((data, header))

##############################################################################
Expand Down
15 changes: 12 additions & 3 deletions sunpy/map/mapbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,8 +679,8 @@ def spatial_units(self):
"""
Image coordinate units along the x and y axes (i.e. cunit1, cunit2).
"""
return SpatialPair(u.Unit(self.meta.get('cunit1', 'arcsec')),
u.Unit(self.meta.get('cunit2', 'arcsec')))
return SpatialPair(u.Unit(self.meta.get('cunit1')),
u.Unit(self.meta.get('cunit2')))

@property
def rotation_matrix(self):
Expand Down Expand Up @@ -773,8 +773,17 @@ def _validate_meta(self):
CUNIT1, CUNIT2, WAVEUNIT
"""
msg = ('Image coordinate units for axis {} not present in metadata. '
'It can be set using `map.meta["cunit{}"] = unit`.')
err_message = []
for i in [1, 2]:
if self.meta.get(f'cunit{i}') is None:
err_message.append(msg.format(i, i))

for meta_property in ('cunit1', 'cunit2', 'waveunit'):
if err_message:
raise AttributeError('\n'.join(err_message))

for meta_property in ('waveunit'):
if (self.meta.get(meta_property) and
u.Unit(self.meta.get(meta_property),
parse_strict='silent').physical_type == 'unknown'):
Expand Down
2 changes: 2 additions & 0 deletions sunpy/map/sources/soho.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ def __init__(self, data, header, **kwargs):
# Fill in some missing info
self.meta['detector'] = "EIT"
self.meta['waveunit'] = "Angstrom"
self.meta['cunit1'] = self.meta.get('cunit1', 'arcsec')
self.meta['cunit2'] = self.meta.get('cunit2', 'arcsec')
self._fix_dsun()
self._nickname = self.detector
self.plot_settings['cmap'] = plt.get_cmap(self._get_cmap_name())
Expand Down
10 changes: 8 additions & 2 deletions sunpy/map/tests/test_mapbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,9 @@ def test_rotation_matrix_cd_cdelt():
'CD2_1': 10,
'CD2_2': 0,
'NAXIS1': 6,
'NAXIS2': 6
'NAXIS2': 6,
'CUNIT1': 'arcsec',
'CUNIT2': 'arcsec'
}
cd_map = sunpy.map.Map((data, header))
np.testing.assert_allclose(cd_map.rotation_matrix, np.array([[0., -1.], [1., 0]]))
Expand All @@ -243,7 +245,9 @@ def test_rotation_matrix_cd_cdelt_square():
'CD2_1': 10,
'CD2_2': 0,
'NAXIS1': 6,
'NAXIS2': 6
'NAXIS2': 6,
'CUNIT1': 'arcsec',
'CUNIT2': 'arcsec'
}
cd_map = sunpy.map.Map((data, header))
np.testing.assert_allclose(cd_map.rotation_matrix, np.array([[0., -1], [1., 0]]))
Expand Down Expand Up @@ -669,6 +673,8 @@ def test_missing_metadata_warnings():
# Checks that warnings for missing metadata are only raised once
with pytest.warns(Warning) as record:
array_map = sunpy.map.Map(np.random.rand(20, 15), {})
array_map.meta['cunit1'] = 'arcsec'
array_map.meta['cunit2'] = 'arcsec'
array_map.peek()
# There should be 4 warnings for missing metadata
assert len([w for w in record if 'Missing metadata' in str(w)]) == 4
Expand Down

0 comments on commit 5254f9c

Please sign in to comment.