From 0104030fabe7780bf39a648c50b2a8ec92888c6a Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Fri, 12 Jan 2024 00:26:38 -0600 Subject: [PATCH 1/5] Allow serializing and deserializing of named astropy units. --- glue/core/state.py | 11 +++++++++++ glue/core/tests/test_state.py | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/glue/core/state.py b/glue/core/state.py index 449005c6a..333f9ffc8 100644 --- a/glue/core/state.py +++ b/glue/core/state.py @@ -65,6 +65,7 @@ def load(rec, context) import numpy as np from matplotlib.colors import Colormap from matplotlib import cm +from astropy.units import NamedUnit, Unit from astropy.wcs import WCS import shapely @@ -621,6 +622,16 @@ def _load_slice(rec, context): return slice(rec['start'], rec['stop'], rec['step']) +@saver(NamedUnit) +def _save_named_unit(unit, context): + return dict(named_unit=unit.to_string()) + + +@loader(NamedUnit) +def _load_named_unit(rec, context): + return Unit(rec["named_unit"]) + + @saver(WCS) def _save_wcs(wcs, context): return dict(header=wcs.to_header_string()) diff --git a/glue/core/tests/test_state.py b/glue/core/tests/test_state.py index 514e9174c..c2be7e0b0 100644 --- a/glue/core/tests/test_state.py +++ b/glue/core/tests/test_state.py @@ -305,6 +305,14 @@ def test_datetime_component(): assert isinstance(c2.data[0], np.datetime64) +@requires_astropy +def test_astropy_units(): + import astropy.units as u + unit = u.m + unit2 = clone(unit) + assert unit2 is unit + + class DummyClass(object): pass From 72ed6765177079ddfda73919740bead0934a4c63 Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Fri, 12 Jan 2024 11:53:48 -0600 Subject: [PATCH 2/5] Update to allow serialization of any UnitBase. --- glue/core/state.py | 14 +++++++------- glue/core/tests/test_state.py | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/glue/core/state.py b/glue/core/state.py index 333f9ffc8..2fc4d3f49 100644 --- a/glue/core/state.py +++ b/glue/core/state.py @@ -65,7 +65,7 @@ def load(rec, context) import numpy as np from matplotlib.colors import Colormap from matplotlib import cm -from astropy.units import NamedUnit, Unit +from astropy.units import UnitBase, Unit from astropy.wcs import WCS import shapely @@ -622,14 +622,14 @@ def _load_slice(rec, context): return slice(rec['start'], rec['stop'], rec['step']) -@saver(NamedUnit) -def _save_named_unit(unit, context): - return dict(named_unit=unit.to_string()) +@saver(UnitBase) +def _save_unit_base(unit, context): + return dict(unit_base=unit.to_string()) -@loader(NamedUnit) -def _load_named_unit(rec, context): - return Unit(rec["named_unit"]) +@loader(UnitBase) +def _load_unit_base(rec, context): + return Unit(rec["unit_base"]) @saver(WCS) diff --git a/glue/core/tests/test_state.py b/glue/core/tests/test_state.py index c2be7e0b0..3656f83b0 100644 --- a/glue/core/tests/test_state.py +++ b/glue/core/tests/test_state.py @@ -312,6 +312,21 @@ def test_astropy_units(): unit2 = clone(unit) assert unit2 is unit + unit = u.km + unit2 = clone(unit) + assert unit2 is unit + + +@requires_astropy +def test_astropy_compound_units(): + import astropy.units as u + unit = u.m / u.s + unit2 = clone(unit) + assert unit2 == unit + unit = u.W / u.m**2 / u.nm + unit2 = clone(unit) + assert unit2 == unit + class DummyClass(object): pass From 58272c173ffa00ef78929d865039924b2db29fe6 Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Wed, 21 Feb 2024 12:17:04 -0500 Subject: [PATCH 3/5] Only allow serializing default units. --- glue/core/state.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/glue/core/state.py b/glue/core/state.py index 2fc4d3f49..b5174a27d 100644 --- a/glue/core/state.py +++ b/glue/core/state.py @@ -65,6 +65,7 @@ def load(rec, context) import numpy as np from matplotlib.colors import Colormap from matplotlib import cm +import astropy.units as u from astropy.units import UnitBase, Unit from astropy.wcs import WCS import shapely @@ -624,7 +625,14 @@ def _load_slice(rec, context): @saver(UnitBase) def _save_unit_base(unit, context): - return dict(unit_base=unit.to_string()) + unit_str = unit.to_string() + # Check that unit can be parsed back with default enabled systems + try: + with u.set_enabled_units([u.si, u.cgs, u.astrophys]): + _ = u.Unit(unit_str) + except ValueError: + raise GlueSerializeError(f"Serializing units of '{unit}' is not yet supported") + return dict(unit_base=unit_str) @loader(UnitBase) From c7801ccf0af565242e8606c3eb0affc0b72e6580 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Thu, 11 Apr 2024 14:47:41 +0100 Subject: [PATCH 4/5] Expand tests Co-authored-by: Derek Homeier <709020+dhomeier@users.noreply.github.com> --- glue/core/tests/test_state.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/glue/core/tests/test_state.py b/glue/core/tests/test_state.py index 3656f83b0..09ce29fd0 100644 --- a/glue/core/tests/test_state.py +++ b/glue/core/tests/test_state.py @@ -317,6 +317,22 @@ def test_astropy_units(): assert unit2 is unit +@requires_astropy +def test_astropy_compound_units(): + import astropy.units as u + unit = u.m / u.s + unit2 = clone(unit) + assert unit2 == unit + + unit = u.W / u.m**2 / u.nm + unit2 = clone(unit) + assert unit2 == unit + + unit = u.km + unit2 = clone(unit) + assert unit2 is unit + + @requires_astropy def test_astropy_compound_units(): import astropy.units as u From 32bc9510a1509b9823c41939700bcaaa1b5aa210 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Tue, 16 Apr 2024 12:28:00 +0100 Subject: [PATCH 5/5] Remove duplicated test --- glue/core/tests/test_state.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/glue/core/tests/test_state.py b/glue/core/tests/test_state.py index 09ce29fd0..e70a5ec51 100644 --- a/glue/core/tests/test_state.py +++ b/glue/core/tests/test_state.py @@ -333,17 +333,6 @@ def test_astropy_compound_units(): assert unit2 is unit -@requires_astropy -def test_astropy_compound_units(): - import astropy.units as u - unit = u.m / u.s - unit2 = clone(unit) - assert unit2 == unit - unit = u.W / u.m**2 / u.nm - unit2 = clone(unit) - assert unit2 == unit - - class DummyClass(object): pass