diff --git a/CHANGES.rst b/CHANGES.rst index 5f19bf5..0dbf016 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,6 +3,7 @@ - Update pins for ``asdf``, ``asdf-coordinates-schemas``, ``numpy``, and ``packaging``. [#164] - Add serialization support for non-VOunits. [#142] +- Add serialization support for ``MagUnit`` based units. [#146] 0.3.0 (2022-11-29) ------------------ diff --git a/asdf_astropy/converters/__init__.py b/asdf_astropy/converters/__init__.py index 6217525..fcb7c43 100644 --- a/asdf_astropy/converters/__init__.py +++ b/asdf_astropy/converters/__init__.py @@ -11,6 +11,7 @@ "EquivalencyConverter", "QuantityConverter", "UnitConverter", + "MagUnitConverter", "FitsConverter", "AsdfFitsConverter", "AstropyFitsConverter", @@ -71,4 +72,4 @@ TransformConverterBase, UnitsMappingConverter, ) -from .unit import EquivalencyConverter, QuantityConverter, UnitConverter +from .unit import EquivalencyConverter, MagUnitConverter, QuantityConverter, UnitConverter diff --git a/asdf_astropy/converters/unit/__init__.py b/asdf_astropy/converters/unit/__init__.py index 975852a..b3efeb3 100644 --- a/asdf_astropy/converters/unit/__init__.py +++ b/asdf_astropy/converters/unit/__init__.py @@ -2,8 +2,10 @@ "EquivalencyConverter", "QuantityConverter", "UnitConverter", + "MagUnitConverter", ] from .equivalency import EquivalencyConverter +from .magunit import MagUnitConverter from .quantity import QuantityConverter from .unit import UnitConverter diff --git a/asdf_astropy/converters/unit/magunit.py b/asdf_astropy/converters/unit/magunit.py new file mode 100644 index 0000000..eb7d3ad --- /dev/null +++ b/asdf_astropy/converters/unit/magunit.py @@ -0,0 +1,17 @@ +from asdf.extension import Converter + + +class MagUnitConverter(Converter): + tags = ["tag:astropy.org:astropy/units/magunit-*"] + + types = [ + "astropy.units.function.logarithmic.MagUnit", + ] + + def to_yaml_tree(self, obj, tag, ctx): + return {"unit": obj.physical_unit} + + def from_yaml_tree(self, node, tag, ctx): + from astropy.units import mag + + return mag(node["unit"]) diff --git a/asdf_astropy/converters/unit/tests/test_magunit.py b/asdf_astropy/converters/unit/tests/test_magunit.py new file mode 100644 index 0000000..28ccd50 --- /dev/null +++ b/asdf_astropy/converters/unit/tests/test_magunit.py @@ -0,0 +1,53 @@ +import asdf +import pytest +from astropy import units + + +def create_builtin_units(): + return [u for u in list(units.__dict__.values()) if isinstance(u, units.MagUnit)] + + +@pytest.mark.parametrize("unit", create_builtin_units()) +@pytest.mark.filterwarnings("ignore::astropy.units.core.UnitsWarning") +def test_builtin_serialization(unit, tmp_path): + file_path = tmp_path / "test.asdf" + with asdf.AsdfFile() as af: + af["unit"] = unit + af.write_to(file_path) + + with asdf.open(file_path) as af: + assert af["unit"].is_equivalent(unit) + + with asdf.open(file_path, _force_raw_types=True) as af: + assert isinstance(af["unit"], asdf.tagged.TaggedDict) + assert af["unit"]._tag.startswith("tag:astropy.org:astropy/units/magunit-") + + +def create_magunits(): + magunits = [] + for u in units.__dict__.values(): + if isinstance(u, units.UnitBase) and not isinstance(u, units.MagUnit): + try: + magunit = units.mag(u) + except units.UnitConversionError: + pass + else: + magunits.append(magunit) + + return magunits + + +@pytest.mark.parametrize("unit", create_magunits()) +@pytest.mark.filterwarnings("ignore::astropy.units.core.UnitsWarning") +def test_magunit_serialization(unit, tmp_path): + file_path = tmp_path / "test.asdf" + with asdf.AsdfFile() as af: + af["unit"] = unit + af.write_to(file_path) + + with asdf.open(file_path) as af: + assert af["unit"].is_equivalent(unit) + + with asdf.open(file_path, _force_raw_types=True) as af: + assert isinstance(af["unit"], asdf.tagged.TaggedDict) + assert af["unit"]._tag.startswith("tag:astropy.org:astropy/units/magunit-") diff --git a/asdf_astropy/extensions.py b/asdf_astropy/extensions.py index 8cc0a40..56d7af6 100644 --- a/asdf_astropy/extensions.py +++ b/asdf_astropy/extensions.py @@ -29,6 +29,7 @@ from .converters.transform.spline import SplineConverter from .converters.transform.tabular import TabularConverter from .converters.unit.equivalency import EquivalencyConverter +from .converters.unit.magunit import MagUnitConverter from .converters.unit.quantity import QuantityConverter from .converters.unit.unit import UnitConverter @@ -512,6 +513,7 @@ UNIT_CONVETERS = [ UnitConverter(), EquivalencyConverter(), + MagUnitConverter(), ] diff --git a/asdf_astropy/resources/manifests/units-1.0.0.yaml b/asdf_astropy/resources/manifests/units-1.0.0.yaml index a0d0fa4..a1a0d92 100644 --- a/asdf_astropy/resources/manifests/units-1.0.0.yaml +++ b/asdf_astropy/resources/manifests/units-1.0.0.yaml @@ -17,3 +17,9 @@ tags: description: |- Supports serialization of equivalencies between units in certain contexts + - tag_uri: tag:astropy.org:astropy/units/magunit-1.0.0 + schema_uri: http://astropy.org/schemas/astropy/units/magunit-1.0.0 + title: Represents a Magnitude Unit + description: |- + Represents the serialization of the MagUnit units built into + astropy. diff --git a/asdf_astropy/resources/schemas/units/magunit-1.0.0.yaml b/asdf_astropy/resources/schemas/units/magunit-1.0.0.yaml new file mode 100644 index 0000000..3644a91 --- /dev/null +++ b/asdf_astropy/resources/schemas/units/magunit-1.0.0.yaml @@ -0,0 +1,18 @@ +%YAML 1.1 +--- +$schema: "http://stsci.edu/schemas/yaml-schema/draft-01" +id: "http://astropy.org/schemas/astropy/units/magunit-1.0.0" + +title: | + Represents a Magnitude Unit + +description: | + Represents the serialization of the MagUnit units built into + astropy. + +type: object +properties: + unit: + oneOf: + - tag: "tag:stsci.edu:asdf/unit/unit-1.0.0" + - tag: "tag:astropy.org:astropy/units/unit-1.0.0"