diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 550d0dc1..eed2ebd0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: default_python: '3.9' envs: | - linux: py39-parallel-cov - - linux: py39-test-devdeps-parallel-cov + - linux: py311-test-devdeps-parallel-cov - linux: py39-astropylts-parallel-cov - linux: py39-transformlts-parallel-cov coverage: codecov @@ -71,6 +71,7 @@ jobs: envs: | - linux: py310-test-parallel - linux: py311-test-parallel + - linux: py312-test-parallel - macos: py311-test-parallel - windows: py311-test-parallel @@ -87,6 +88,7 @@ jobs: envs: | - linux: py310-test-devdeps-parallel - linux: py311-test-devdeps-parallel + - linux: py311-test-devdeps-numpydev-parallel oldest: needs: [core, asdf-schemas] @@ -102,24 +104,6 @@ jobs: - linux: py39-test-oldestdep-parallels-cov coverage: codecov - numpy: - needs: [core, asdf-schemas] - uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@v1 - with: - cache-path: ~/.cache/pip - cache-key: pip-${{ needs.setup.outputs.requirements-hash }} - cache-restore-keys: | - pip- - # Any env name which does not start with `pyXY` will use this Python version. - default_python: '3.9' - envs: | - - linux: py39-test-numpy119-parallel - - linux: py39-test-numpy120-parallel - - linux: py310-test-numpy121-parallel - - linux: py310-test-numpy122-parallel - - linux: py311-test-numpy123-parallel - - linux: py311-test-numpy124-parallel - wheel_building: permissions: contents: none diff --git a/CHANGES.rst b/CHANGES.rst index c1f86ebd..d72b3061 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,12 @@ +0.6.0 (unreleased) +------------------ + +- Add python 3.12 support. [#219] +- Update ASDF standard 1.6.0 support. [#219] +- Increase minimum versions for ``asdf-coordinates-schemas`` + ``asdf-transform-schemas`` and list ``asdf-standard`` as + a dependency. [#219] + 0.5.0 (2023-11-15) ------------------ diff --git a/asdf_astropy/_manifest.py b/asdf_astropy/_manifest.py deleted file mode 100644 index 67955273..00000000 --- a/asdf_astropy/_manifest.py +++ /dev/null @@ -1,40 +0,0 @@ -import re -from itertools import chain - -from asdf import extension - - -class CompoundManifestExtension(extension.Extension): - """ - Combine a listed of asdf ``ManifestExtensions`` into a single extension. - """ - - def __init__(self, extensions): - self._extensions = extensions - # overwrite extension uri from first extension (the one from asdf-standard) - # so that this extension uses a new, unique uri - self._extension_uri = re.sub("asdf-format", "astropy", extensions[0].extension_uri) - - @property - def extension_uri(self): - return self._extension_uri - - @property - def asdf_standard_requirement(self): - return self._extensions[0].asdf_standard_requirement - - @property - def legacy_class_names(self): - return list(chain.from_iterable(e.legacy_class_names for e in self._extensions)) - - @property - def converters(self): - return list(chain.from_iterable(e.converters for e in self._extensions)) - - @property - def compressors(self): - return list(chain.from_iterable(e.compressors for e in self._extensions)) - - @property - def tags(self): - return list(chain.from_iterable(e.tags for e in self._extensions)) diff --git a/asdf_astropy/converters/coordinates/tests/test_frame.py b/asdf_astropy/converters/coordinates/tests/test_frame.py index 1b2a5414..0d29aa4f 100644 --- a/asdf_astropy/converters/coordinates/tests/test_frame.py +++ b/asdf_astropy/converters/coordinates/tests/test_frame.py @@ -115,7 +115,7 @@ def test_legacy_icrs_deseialize(): unit: deg""" truth = ICRS(ra=Longitude(25, unit=u.deg), dec=Latitude(45, unit=u.deg)) - buff = yaml_to_asdf(f"example: {example.strip()}") + buff = yaml_to_asdf(f"example: {example.strip()}", version="1.5.0") with asdf.AsdfFile() as af: af._open_impl(af, buff, mode="rw") assert_frame_equal(af["example"], truth) diff --git a/asdf_astropy/converters/fits/tests/test_fits.py b/asdf_astropy/converters/fits/tests/test_fits.py index 20978890..20fcdd7f 100644 --- a/asdf_astropy/converters/fits/tests/test_fits.py +++ b/asdf_astropy/converters/fits/tests/test_fits.py @@ -83,7 +83,7 @@ def test_asdf_tag(): - [BUNIT, DN, Units of the error array] """ - buff = yaml_to_asdf(yaml) + buff = yaml_to_asdf(yaml, version="1.5.0") with asdf.open(buff) as af: hdul = af["hdul"] assert len(hdul) == 3 # noqa: PLR2004 diff --git a/asdf_astropy/converters/table/table.py b/asdf_astropy/converters/table/table.py index 2e771f9e..b7918842 100644 --- a/asdf_astropy/converters/table/table.py +++ b/asdf_astropy/converters/table/table.py @@ -3,7 +3,10 @@ class ColumnConverter(Converter): - tags = ("tag:stsci.edu:asdf/core/column-*",) + tags = ( + "tag:stsci.edu:asdf/core/column-*", + "tag:stsci.edu:asdf/table/column-*", + ) types = ( "astropy.table.column.Column", "astropy.table.column.MaskedColumn", @@ -45,7 +48,10 @@ def from_yaml_tree(self, node, tag, ctx): class AsdfTableConverter(Converter): - tags = ("tag:stsci.edu:asdf/core/table-*",) + tags = ( + "tag:stsci.edu:asdf/core/table-*", + "tag:stsci.edu:asdf/table/table-*", + ) types = () def to_yaml_tree(self, obj, tag, ctx): diff --git a/asdf_astropy/converters/table/tests/test_table.py b/asdf_astropy/converters/table/tests/test_table.py index ad1c70e6..b3acdc8b 100644 --- a/asdf_astropy/converters/table/tests/test_table.py +++ b/asdf_astropy/converters/table/tests/test_table.py @@ -139,7 +139,7 @@ def test_mismatched_columns(): colnames: [a, b] """ - buff = yaml_to_asdf(yaml) + buff = yaml_to_asdf(yaml, version="1.5.0") with pytest.raises(ValueError, match="Inconsistent data column lengths"), asdf.open(buff): pass @@ -251,7 +251,7 @@ def test_asdf_table(): description: The target name name: c """ - buff = yaml_to_asdf(yaml) + buff = yaml_to_asdf(yaml, version="1.5.0") with asdf.open(buff) as af: table = af["table"] diff --git a/asdf_astropy/converters/time/tests/test_time.py b/asdf_astropy/converters/time/tests/test_time.py index 01572065..6559fe34 100644 --- a/asdf_astropy/converters/time/tests/test_time.py +++ b/asdf_astropy/converters/time/tests/test_time.py @@ -111,7 +111,7 @@ def create_examples(): @pytest.mark.parametrize("example", create_examples()) def test_read_examples(example): - buff = yaml_to_asdf(f"example: {example['example'].strip()}") + buff = yaml_to_asdf(f"example: {example['example'].strip()}", version="1.5.0") with asdf.AsdfFile() as af: af._open_impl(af, buff, mode="rw") assert np.all(af["example"] == example["truth"]) @@ -133,6 +133,10 @@ def create_formats(): formats = [] for format_ in TIME_FORMATS: + if format_ == "stardate": + # stardate is not a documented format for astropy + # https://docs.astropy.org/en/latest/time/index.html#time-format + continue new = Time("B2000.0") new.format = format_ formats.append(new) diff --git a/asdf_astropy/converters/transform/properties.py b/asdf_astropy/converters/transform/properties.py index 5c0d8b64..b9a69533 100644 --- a/asdf_astropy/converters/transform/properties.py +++ b/asdf_astropy/converters/transform/properties.py @@ -3,7 +3,7 @@ class ModelBoundingBoxConverter(Converter): - tags = ("tag:stsci.edu:asdf/transform/property/bounding_box-1.0.0",) + tags = ("tag:stsci.edu:asdf/transform/property/bounding_box-*",) types = ("astropy.modeling.bounding_box.ModelBoundingBox",) def to_yaml_tree(self, bbox, tag, ctx): @@ -40,7 +40,7 @@ def create_bounding_box(model, cbbox=None): class CompoundBoundingBoxConverter(Converter): - tags = ("tag:stsci.edu:asdf/transform/property/compound_bounding_box-1.0.0",) + tags = ("tag:stsci.edu:asdf/transform/property/compound_bounding_box-*",) types = ("astropy.modeling.bounding_box.CompoundBoundingBox",) def to_yaml_tree(self, cbbox, tag, ctx): diff --git a/asdf_astropy/converters/transform/tests/test_transform.py b/asdf_astropy/converters/transform/tests/test_transform.py index e8ccc7bf..6c7790b3 100644 --- a/asdf_astropy/converters/transform/tests/test_transform.py +++ b/asdf_astropy/converters/transform/tests/test_transform.py @@ -529,6 +529,7 @@ def test_all_models_supported(model): def test_legacy_const(tmp_path): with asdf.config_context() as config: + config.remove_extension("asdf://asdf-format.org/transform/extensions/transform-1.6.0") config.remove_extension("asdf://asdf-format.org/transform/extensions/transform-1.5.0") model = astropy_models.Const1D(amplitude=5.0) diff --git a/asdf_astropy/converters/unit/tests/test_quantity.py b/asdf_astropy/converters/unit/tests/test_quantity.py index 42fc30ef..2595131c 100644 --- a/asdf_astropy/converters/unit/tests/test_quantity.py +++ b/asdf_astropy/converters/unit/tests/test_quantity.py @@ -44,7 +44,7 @@ def test_read_untagged_unit(): value: {value} unit: kpc """ - buff = helpers.yaml_to_asdf(yaml) + buff = helpers.yaml_to_asdf(yaml, version="1.5.0") with asdf.open(buff) as af: assert af["quantity"].value == value assert af["quantity"].unit.is_equivalent(units.kpc) @@ -57,7 +57,7 @@ def test_read_tagged_unit(): value: {value} unit: !unit/unit-1.0.0 kpc """ - buff = helpers.yaml_to_asdf(yaml) + buff = helpers.yaml_to_asdf(yaml, version="1.5.0") with asdf.open(buff) as af: assert af["quantity"].value == value assert af["quantity"].unit.is_equivalent(units.kpc) @@ -69,7 +69,7 @@ def test_read_array_value(): value: !core/ndarray-1.0.0 [1.0, 2.0, 3.0, 4.0] unit: km """ - buff = helpers.yaml_to_asdf(yaml) + buff = helpers.yaml_to_asdf(yaml, version="1.5.0") with asdf.open(buff) as af: assert_array_equal(af["quantity"].value, np.array([1.0, 2.0, 3.0, 4.0])) assert af["quantity"].unit.is_equivalent(units.km) diff --git a/asdf_astropy/extensions.py b/asdf_astropy/extensions.py index 5f5dba55..bace370e 100644 --- a/asdf_astropy/extensions.py +++ b/asdf_astropy/extensions.py @@ -6,7 +6,6 @@ from asdf.extension import ManifestExtension from astropy.utils import minversion -from ._manifest import CompoundManifestExtension from .converters.coordinates.angle import AngleConverter, LatitudeConverter, LongitudeConverter from .converters.coordinates.earth_location import EarthLocationConverter from .converters.coordinates.frame import FrameConverter, LegacyICRSConverter @@ -39,11 +38,12 @@ "TRANSFORM_EXTENSIONS", "COORDINATES_CONVERTERS", "ASTROPY_CONVERTERS", - "COORDINATES_EXTENSION", + "COORDINATES_EXTENSIONS", "ASTROPY_EXTENSIONS", "CORE_CONVERTERS", "CORE_MANIFEST_URIS", "CORE_EXTENSIONS", + "UNIT_EXTENSIONS", ] TRANSFORM_CONVERTERS = [ @@ -399,6 +399,7 @@ # The order here is important; asdf will prefer to use extensions # that occur earlier in the list. TRANSFORM_MANIFEST_URIS = [ + "asdf://asdf-format.org/transform/manifests/transform-1.6.0", "asdf://asdf-format.org/transform/manifests/transform-1.5.0", "asdf://asdf-format.org/transform/manifests/transform-1.4.0", "asdf://asdf-format.org/transform/manifests/transform-1.3.0", @@ -407,7 +408,6 @@ "asdf://asdf-format.org/transform/manifests/transform-1.0.0", ] - TRANSFORM_EXTENSIONS = [ ManifestExtension.from_uri( uri, @@ -484,14 +484,22 @@ NdarrayMixinConverter(), ] - -COORDINATES_EXTENSION = ManifestExtension.from_uri( +_COORDINATES_MANIFEST_URIS = [ + "asdf://asdf-format.org/astronomy/coordinates/manifests/coordinates-1.1.0", "asdf://asdf-format.org/astronomy/coordinates/manifests/coordinates-1.0.0", - converters=COORDINATES_CONVERTERS, -) +] + +COORDINATES_EXTENSIONS = [ + ManifestExtension.from_uri( + manifest_uri, + converters=COORDINATES_CONVERTERS, + ) + for manifest_uri in _COORDINATES_MANIFEST_URIS +] _ASTROPY_EXTENSION_MANIFEST_URIS = [ + "asdf://astropy.org/astropy/manifests/astropy-1.2.0", "asdf://astropy.org/astropy/manifests/astropy-1.1.0", "asdf://astropy.org/astropy/manifests/astropy-1.0.0", ] @@ -508,42 +516,49 @@ for manifest_uri in _ASTROPY_EXTENSION_MANIFEST_URIS ] + # These tags are part of the ASDF Standard, # but we want to override serialization here so that users can # work with nice astropy objects for those entities. +_FITS_CONVERTERS = [ + AsdfFitsConverter(), +] -CORE_CONVERTERS = [ - QuantityConverter(), +_TIME_CONVERTERS = [ TimeConverter(), +] + +_TABLE_CONVERTERS = [ ColumnConverter(), AsdfTableConverter(), - AsdfFitsConverter(), ] -UNIT_CONVETERS = [ +_UNIT_CONVERTERS = [ UnitConverter(), EquivalencyConverter(), MagUnitConverter(), + QuantityConverter(), ] +CORE_CONVERTERS = _FITS_CONVERTERS + _TIME_CONVERTERS + _TABLE_CONVERTERS + _UNIT_CONVERTERS +UNIT_EXTENSIONS = [ + ManifestExtension.from_uri( + "asdf://astropy.org/astropy/manifests/units-1.0.0", + converters=_UNIT_CONVERTERS, + ), +] + +# up to asdf 1.5.0 many tags supported by asdf-astropy +# were defined in core manifests CORE_MANIFEST_URIS = [ - "asdf://asdf-format.org/core/manifests/core-1.0.0", - "asdf://asdf-format.org/core/manifests/core-1.1.0", - "asdf://asdf-format.org/core/manifests/core-1.2.0", - "asdf://asdf-format.org/core/manifests/core-1.3.0", - "asdf://asdf-format.org/core/manifests/core-1.4.0", + "asdf://asdf-format.org/astronomy/manifests/astronomy-1.0.0", "asdf://asdf-format.org/core/manifests/core-1.5.0", - "asdf://asdf-format.org/core/manifests/core-1.6.0", + "asdf://asdf-format.org/core/manifests/core-1.4.0", + "asdf://asdf-format.org/core/manifests/core-1.3.0", + "asdf://asdf-format.org/core/manifests/core-1.2.0", + "asdf://asdf-format.org/core/manifests/core-1.1.0", + "asdf://asdf-format.org/core/manifests/core-1.0.0", ] - -CORE_EXTENSIONS = [ - CompoundManifestExtension( - [ - ManifestExtension.from_uri(u, converters=CORE_CONVERTERS), - ManifestExtension.from_uri("asdf://astropy.org/astropy/manifests/units-1.0.0", converters=UNIT_CONVETERS), - ], - ) - for u in CORE_MANIFEST_URIS -] +CORE_EXTENSIONS = [ManifestExtension.from_uri(u, converters=CORE_CONVERTERS) for u in CORE_MANIFEST_URIS] diff --git a/asdf_astropy/integration.py b/asdf_astropy/integration.py index d0ad2e36..d243c919 100644 --- a/asdf_astropy/integration.py +++ b/asdf_astropy/integration.py @@ -37,7 +37,8 @@ def get_extensions(): return [ *extensions.ASTROPY_EXTENSIONS, - extensions.COORDINATES_EXTENSION, + *extensions.COORDINATES_EXTENSIONS, *extensions.TRANSFORM_EXTENSIONS, + *extensions.UNIT_EXTENSIONS, *extensions.CORE_EXTENSIONS, ] diff --git a/asdf_astropy/resources/manifests/astropy-1.2.0.yaml b/asdf_astropy/resources/manifests/astropy-1.2.0.yaml new file mode 100644 index 00000000..a3429f33 --- /dev/null +++ b/asdf_astropy/resources/manifests/astropy-1.2.0.yaml @@ -0,0 +1,56 @@ +id: asdf://astropy.org/astropy/manifests/astropy-1.2.0 +extension_uri: asdf://astropy.org/astropy/extensions/astropy-1.2.0 +title: Astropy extension 1.2.0 +description: |- + A set of tags for serializing astropy objects. This does not include most + model classes, which are handled by an implementation of the ASDF + transform extension. +asdf_standard_requirement: + gte: 1.6.0 +tags: +- tag_uri: tag:astropy.org:astropy/time/timedelta-1.1.0 + schema_uri: http://astropy.org/schemas/astropy/time/timedelta-1.1.0 + title: Represents an instance of TimeDelta from astropy + description: |- + Represents the time difference between two times. +- tag_uri: tag:astropy.org:astropy/fits/fits-1.1.0 + schema_uri: http://astropy.org/schemas/astropy/fits/fits-1.1.0 + title: A FITS file inside of an ASDF file. + description: |- + This schema is useful for distributing ASDF files that can + automatically be converted to FITS files by specifying the exact + content of the resulting FITS file. + + Not all kinds of data in FITS are directly representable in ASDF. + For example, applying an offset and scale to the data using the + `BZERO` and `BSCALE` keywords. In these cases, it will not be + possible to store the data in the native format from FITS and also + be accessible in its proper form in the ASDF file. + + Only image and binary table extensions are supported. +- tag_uri: tag:astropy.org:astropy/table/table-1.2.0 + schema_uri: http://astropy.org/schemas/astropy/table/table-1.2.0 + title: A table. + description: |- + A table is represented as a list of columns, where each entry is a + [column](ref:http://stsci.edu/schemas/asdf/table/column-1.1.0) + object, containing the data and some additional information. + + The data itself may be stored inline as text, or in binary in either + row- or column-major order by use of the `strides` property on the + individual column arrays. + + Each column in the table must have the same first (slowest moving) + dimension. +- tag_uri: tag:astropy.org:astropy/transform/units_mapping-1.1.0 + schema_uri: http://astropy.org/schemas/astropy/transform/units_mapping-1.1.0 + title: Mapper that operates on the units of the input. + description: |- + This transform operates on the units of the input, first converting to + the expected input units, then assigning replacement output units without + further conversion. +- tag_uri: tag:astropy.org:astropy/table/ndarraymixin-1.0.0 + schema_uri: http://astropy.org/schemas/astropy/table/ndarraymixin-1.0.0 + title: NdarrayMixin column. + description: |- + Represents an astropy.table.NdarrayMixin instance. diff --git a/asdf_astropy/resources/manifests/units-1.0.0.yaml b/asdf_astropy/resources/manifests/units-1.0.0.yaml index a1a0d923..af96a508 100644 --- a/asdf_astropy/resources/manifests/units-1.0.0.yaml +++ b/asdf_astropy/resources/manifests/units-1.0.0.yaml @@ -6,6 +6,14 @@ description: |- A set of tags to inject into asdf-standard to enable serializing astropy units related objects tags: + # unit/unit is duplicated from the core to allow the unit converter to select + # the core tag for vo units + - tag_uri: tag:stsci.edu:asdf/unit/unit-1.0.0 + schema_uri: http://stsci.edu/schemas/asdf/unit/unit-1.0.0 + title: Physical unit. + description: |- + This represents a physical unit, in [VOUnit syntax, Version 1.0](http://www.ivoa.net/documents/VOUnits/index.html). + Where units are not explicitly tagged, they are assumed to be in VOUnit syntax. - tag_uri: tag:astropy.org:astropy/units/unit-1.0.0 schema_uri: http://stsci.edu/schemas/asdf/unit/unit-1.0.0 title: Represents an astropy derived unit diff --git a/asdf_astropy/resources/manifests/units-1.1.0.yaml b/asdf_astropy/resources/manifests/units-1.1.0.yaml new file mode 100644 index 00000000..54282d4d --- /dev/null +++ b/asdf_astropy/resources/manifests/units-1.1.0.yaml @@ -0,0 +1,27 @@ + +id: asdf://astropy.org/astropy/manifests/units-1.1.0 +extension_uri: asdf://astropy.org/astropy/extensions/units-1.1.0 +title: Astropy unit extension 1.0.0 +description: |- + A set of tags to inject into asdf-standard to enable serializing astropy units + related objects +asdf_standard_requirement: + gte: 1.6.0 +tags: + - tag_uri: tag:astropy.org:astropy/units/unit-1.0.0 + schema_uri: http://stsci.edu/schemas/asdf/unit/unit-1.0.0 + title: Represents an astropy derived unit + description: |- + Supports serialization of the non-VOunits supported by astropy + - tag_uri: tag:astropy.org:astropy/units/equivalency-1.1.0 + schema_uri: http://astropy.org/schemas/astropy/units/equivalency-1.1.0 + title: Represents unit equivalency. + 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/fits/fits-1.0.0.yaml b/asdf_astropy/resources/schemas/fits/fits-1.0.0.yaml index 81cbcd19..9ecfe42c 100644 --- a/asdf_astropy/resources/schemas/fits/fits-1.0.0.yaml +++ b/asdf_astropy/resources/schemas/fits/fits-1.0.0.yaml @@ -20,6 +20,7 @@ description: | examples: - - A simple FITS file with a primary header and two extensions + - asdf-standard-1.5.0 - | ! - header: diff --git a/asdf_astropy/resources/schemas/fits/fits-1.1.0.yaml b/asdf_astropy/resources/schemas/fits/fits-1.1.0.yaml new file mode 100644 index 00000000..4c89831b --- /dev/null +++ b/asdf_astropy/resources/schemas/fits/fits-1.1.0.yaml @@ -0,0 +1,93 @@ +%YAML 1.1 +--- +$schema: "http://stsci.edu/schemas/yaml-schema/draft-01" +id: "http://astropy.org/schemas/astropy/fits/fits-1.1.0" +title: > + A FITS file inside of an ASDF file. +description: | + This schema is useful for distributing ASDF files that can + automatically be converted to FITS files by specifying the exact + content of the resulting FITS file. + + Not all kinds of data in FITS are directly representable in ASDF. + For example, applying an offset and scale to the data using the + `BZERO` and `BSCALE` keywords. In these cases, it will not be + possible to store the data in the native format from FITS and also + be accessible in its proper form in the ASDF file. + + Only image and binary table extensions are supported. + +examples: + - + - A simple FITS file with a primary header and two extensions + - asdf-standard-1.6.0 + - | + ! + - header: + - [SIMPLE, true, conforms to FITS standard] + - [BITPIX, 8, array data type] + - [NAXIS, 0, number of array dimensions] + - [EXTEND, true] + - [] + - ['', Top Level MIRI Metadata] + - [] + - [DATE, '2013-08-30T10:49:55.070373', The date this file was created (UTC)] + - [FILENAME, MiriDarkReferenceModel_test.fits, The name of the file] + - [TELESCOP, JWST, The telescope used to acquire the data] + - [] + - ['', Information about the observation] + - [] + - [DATE-OBS, '2013-08-30T10:49:55.000000', The date the observation was made (UTC)] + - data: !core/ndarray-1.1.0 + datatype: float32 + shape: [2, 3, 3, 4] + source: 0 + byteorder: big + header: + - [XTENSION, IMAGE, Image extension] + - [BITPIX, -32, array data type] + - [NAXIS, 4, number of array dimensions] + - [NAXIS1, 4] + - [NAXIS2, 3] + - [NAXIS3, 3] + - [NAXIS4, 2] + - [PCOUNT, 0, number of parameters] + - [GCOUNT, 1, number of groups] + - [EXTNAME, SCI, extension name] + - [BUNIT, DN, Units of the data array] + - data: !core/ndarray-1.1.0 + datatype: float32 + shape: [2, 3, 3, 4] + source: 1 + byteorder: big + header: + - [XTENSION, IMAGE, Image extension] + - [BITPIX, -32, array data type] + - [NAXIS, 4, number of array dimensions] + - [NAXIS1, 4] + - [NAXIS2, 3] + - [NAXIS3, 3] + - [NAXIS4, 2] + - [PCOUNT, 0, number of parameters] + - [GCOUNT, 1, number of groups] + - [EXTNAME, ERR, extension name] + - [BUNIT, DN, Units of the error array] + +allOf: + - tag: "tag:astropy.org:astropy/fits/fits-1.1.0" + - type: array + items: + type: object + properties: + # TODO: Why are there no validations for the header here? The + # next version of the schema should add them. + data: + description: "The data part of the HDU." + anyOf: + - $ref: "http://stsci.edu/schemas/asdf/core/ndarray-1.1.0" + - $ref: "../table/table-1.2.0" + # Retain backwards compatibility with table defined by ASDF Standard + - $ref: "http://stsci.edu/schemas/asdf/table/table-1.1.0" + - $ref: "http://stsci.edu/schemas/asdf/core/table-1.0.0" + - type: "null" + default: null diff --git a/asdf_astropy/resources/schemas/table/table-1.0.0.yaml b/asdf_astropy/resources/schemas/table/table-1.0.0.yaml index 30426550..54eb3ac8 100644 --- a/asdf_astropy/resources/schemas/table/table-1.0.0.yaml +++ b/asdf_astropy/resources/schemas/table/table-1.0.0.yaml @@ -21,6 +21,7 @@ description: | examples: - - A table stored in column-major order, with each column in a separate block + - asdf-standard-1.5.0 - | ! columns: @@ -54,6 +55,7 @@ examples: - - A table stored in row-major order, all stored in the same block + - asdf-standard-1.5.0 - | ! columns: diff --git a/asdf_astropy/resources/schemas/table/table-1.1.0.yaml b/asdf_astropy/resources/schemas/table/table-1.1.0.yaml index 1a6873d4..0f443c93 100644 --- a/asdf_astropy/resources/schemas/table/table-1.1.0.yaml +++ b/asdf_astropy/resources/schemas/table/table-1.1.0.yaml @@ -21,6 +21,7 @@ description: | examples: - - A table stored in column-major order, with each column in a separate block + - asdf-standard-1.5.0 - | ! columns: @@ -54,6 +55,7 @@ examples: - - A table stored in row-major order, all stored in the same block + - asdf-standard-1.5.0 - | ! columns: diff --git a/asdf_astropy/resources/schemas/table/table-1.2.0.yaml b/asdf_astropy/resources/schemas/table/table-1.2.0.yaml new file mode 100644 index 00000000..f5eb8193 --- /dev/null +++ b/asdf_astropy/resources/schemas/table/table-1.2.0.yaml @@ -0,0 +1,133 @@ +%YAML 1.1 +--- +$schema: "http://stsci.edu/schemas/yaml-schema/draft-01" +id: "http://astropy.org/schemas/astropy/table/table-1.2.0" + +title: > + A table. + +description: | + A table is represented as a list of columns, where each entry is a + [column](https://asdf-standard.readthedocs.io/en/latest/generated/stsci.edu/asdf/table/column-1.1.0.html) + object, containing the data and some additional information. + + The data itself may be stored inline as text, or in binary in either + row- or column-major order by use of the `strides` property on the + individual column arrays. + + Each column in the table must have the same first (slowest moving) + dimension. + +examples: + - + - A table stored in column-major order, with each column in a separate block + - asdf-standard-1.6.0 + - | + ! + columns: + - !table/column-1.1.0 + data: !core/ndarray-1.1.0 + source: 0 + datatype: float64 + byteorder: little + shape: [3] + description: RA + meta: {foo: bar} + name: a + unit: !unit/unit-1.0.0 deg + - !table/column-1.1.0 + data: !core/ndarray-1.1.0 + source: 1 + datatype: float64 + byteorder: little + shape: [3] + description: DEC + name: b + - !table/column-1.1.0 + data: !core/ndarray-1.1.0 + source: 2 + datatype: [ascii, 1] + byteorder: big + shape: [3] + description: The target name + name: c + colnames: [a, b, c] + + - + - A table stored in row-major order, all stored in the same block + - asdf-standard-1.6.0 + - | + ! + columns: + - !table/column-1.1.0 + data: !core/ndarray-1.1.0 + source: 0 + datatype: float64 + byteorder: little + shape: [3] + strides: [13] + description: RA + meta: {foo: bar} + name: a + unit: !unit/unit-1.0.0 deg + - !table/column-1.1.0 + data: !core/ndarray-1.1.0 + source: 0 + datatype: float64 + byteorder: little + shape: [3] + offset: 4 + strides: [13] + description: DEC + name: b + - !table/column-1.1.0 + data: !core/ndarray-1.1.0 + source: 0 + datatype: [ascii, 1] + byteorder: big + shape: [3] + offset: 12 + strides: [13] + description: The target name + name: c + colnames: [a, b, c] + +type: object +properties: + columns: + description: | + A list of columns in the table. + type: array + items: + anyOf: + - $ref: "http://stsci.edu/schemas/asdf/core/column-1.0.0" + - $ref: "http://stsci.edu/schemas/asdf/table/column-1.1.0" + - $ref: "http://stsci.edu/schemas/asdf/core/ndarray-1.1.0" + - $ref: "http://stsci.edu/schemas/asdf/time/time-1.2.0" + - $ref: "http://stsci.edu/schemas/asdf/unit/quantity-1.2.0" + - $ref: "../coordinates/skycoord-1.0.0" + - $ref: "../coordinates/earthlocation-1.1.0" + - $ref: "../time/timedelta-1.1.0" + - $ref: "ndarraymixin-1.0.0" + + colnames: + description: | + A list containing the names of the columns in the table (in order). + type: array + items: + - type: string + + qtable: + description: | + A flag indicating whether or not the serialized type was a QTable + type: boolean + default: False + + meta: + description: | + Additional free-form metadata about the table. + type: object + default: {} + +additionalProperties: false +required: [columns, colnames] diff --git a/asdf_astropy/resources/schemas/time/timedelta-1.1.0.yaml b/asdf_astropy/resources/schemas/time/timedelta-1.1.0.yaml new file mode 100644 index 00000000..5e48a976 --- /dev/null +++ b/asdf_astropy/resources/schemas/time/timedelta-1.1.0.yaml @@ -0,0 +1,34 @@ +%YAML 1.1 +--- +$schema: "http://stsci.edu/schemas/asdf/asdf-schema-1.0.0" +id: "http://astropy.org/schemas/astropy/time/timedelta-1.1.0" +title: Represents an instance of TimeDelta from astropy +description: | + Represents the time difference between two times. + +type: object +properties: + jd1: + anyOf: + - type: number + - $ref: "http://stsci.edu/schemas/asdf/core/ndarray-1.1.0" + description: | + Value representing first 64 bits of precision + jd2: + anyOf: + - type: number + - $ref: "http://stsci.edu/schemas/asdf/core/ndarray-1.1.0" + description: | + Value representing second 64 bits of precision + format: + type: string + description: | + Format of time value representation. + scale: + type: string + description: | + Time scale of input value(s). + enum: [tdb, tt, ut1, tcg, tcb, tai, local] +required: [jd1, jd2, format] +additionalProperties: False +... diff --git a/asdf_astropy/resources/schemas/transform/units_mapping-1.1.0.yaml b/asdf_astropy/resources/schemas/transform/units_mapping-1.1.0.yaml new file mode 100644 index 00000000..4bea4291 --- /dev/null +++ b/asdf_astropy/resources/schemas/transform/units_mapping-1.1.0.yaml @@ -0,0 +1,102 @@ +%YAML 1.1 +--- +$schema: "http://stsci.edu/schemas/yaml-schema/draft-01" +id: "http://astropy.org/schemas/astropy/transform/units_mapping-1.1.0" + +title: | + Mapper that operates on the units of the input. + +description: | + This transform operates on the units of the input, first converting to + the expected input units, then assigning replacement output units without + further conversion. + +examples: + - + - Assign units of seconds to dimensionless input. + - asdf-standard-1.6.0 + - | + ! + unit_inputs: + - name: x + unit: !unit/unit-1.0.0 + unit_outputs: + - name: x + unit: !unit/unit-1.0.0 s + - + - Convert input to meters, then assign dimensionless units. + - asdf-standard-1.6.0 + - | + ! + unit_inputs: + - name: x + unit: !unit/unit-1.0.0 m + unit_outputs: + - name: x + unit: !unit/unit-1.0.0 + + - + - Convert input to meters, then drop units entirely. + - asdf-standard-1.6.0 + - | + ! + unit_inputs: + - name: x + unit: !unit/unit-1.0.0 m + unit_outputs: + - name: x + + - + - Accept any units, then replace with meters. + - asdf-standard-1.6.0 + - | + ! + unit_inputs: + - name: x + unit_outputs: + - name: x + unit: !unit/unit-1.0.0 m + +allOf: + - $ref: "http://stsci.edu/schemas/asdf/transform/transform-1.3.0" + - type: object + properties: + unit_inputs: + description: | + Array of input configurations. + type: array + items: + $ref: "#/definitions/value_configuration" + unit_outputs: + description: | + Array of output configurations. + type: array + items: + $ref: "#/definitions/value_configuration" + required: [unit_inputs, unit_outputs] + +definitions: + value_configuration: + description: | + Configuration of a single model value (input or output). + type: object + properties: + name: + description: | + Value name. + type: string + unit: + description: | + Expected unit. + $ref: "http://stsci.edu/schemas/asdf/unit/unit-1.0.0" + equivalencies: + description: | + Equivalencies to apply when converting value to expected unit. + $ref: "http://astropy.org/schemas/astropy/units/equivalency-1.1.0" + allow_dimensionless: + description: | + Allow this value to receive dimensionless data. + type: boolean + default: false + required: [name] +... diff --git a/asdf_astropy/resources/schemas/units/equivalency-1.1.0.yaml b/asdf_astropy/resources/schemas/units/equivalency-1.1.0.yaml new file mode 100644 index 00000000..db4c5890 --- /dev/null +++ b/asdf_astropy/resources/schemas/units/equivalency-1.1.0.yaml @@ -0,0 +1,34 @@ +%YAML 1.1 +--- +$schema: "http://stsci.edu/schemas/yaml-schema/draft-01" +id: "http://astropy.org/schemas/astropy/units/equivalency-1.1.0" + +title: | + Represents unit equivalency. + +description: | + Supports serialization of equivalencies between units + in certain contexts + +definitions: + equivalency: + type: object + properties: + name: + type: string + kwargs_names: + type: array + items: + type: string + kwargs_values: + type: array + items: + anyOf: + - $ref: "http://stsci.edu/schemas/asdf/unit/quantity-1.2.0" + - type: number + - type: "null" + +type: array +items: + $ref: "#/definitions/equivalency" +... diff --git a/pyproject.toml b/pyproject.toml index ce7a56d5..eb915a72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,14 +12,16 @@ classifiers = [ 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] dynamic = [ 'version', ] dependencies = [ "asdf>=2.13", - "asdf-coordinates-schemas>=0.1", - "asdf-transform-schemas>=0.2.2", + "asdf-coordinates-schemas>=0.3", + "asdf-transform-schemas>=0.5", + "asdf-standard>=1.1.0", "astropy>=5.0.4", "numpy>=1.20", "packaging>=19", @@ -39,6 +41,7 @@ test = [ "coverage", "pytest-astropy", "scipy", + "pytest", ] [project.urls] 'documentation' = 'https://asdf-astropy.readthedocs.io/en/latest/' diff --git a/requirements-dev.txt b/requirements-dev.txt index e719b09b..a80bbd39 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,7 +1,7 @@ -git+https://github.com/astropy/astropy git+https://github.com/asdf-format/asdf git+https://github.com/asdf-format/asdf-standard.git git+https://github.com/asdf-format/asdf-transform-schemas +git+https://github.com/asdf-format/asdf-coordinates-schemas scipy>=0.0.dev0 numpy>=0.0.dev0 diff --git a/tox.ini b/tox.ini index fea0b5ed..212451bc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,8 @@ [tox] envlist = py{39,310}-test{,-alldeps} - py38-test-devdeps + py38-test-devdeps{,-numpydev} py38-cov - py{39,}-test-numpy{119,120,121,122} py38-astropylts py39-test-oldestdep-parallels-cov requires = @@ -17,12 +16,6 @@ description = alldeps: with all optional dependencies devdeps: with the latest developer version of key dependencies cov: and test coverage - numpy119: with numpy 1.19.* - numpy120: with numpy 1.20.* - numpy121: with numpy 1.21.* - numpy122: with numpy 1.22.* - numpy123: with numpy 1.23.* - numpy124: with numpy 1.24.* astropylts: with astropy LTS setenv = @@ -31,12 +24,6 @@ setenv = # The following provides some specific pinnings for key packages deps = cov: coverage - numpy119: numpy==1.19.* - numpy120: numpy==1.20.* - numpy121: numpy==1.21.* - numpy122: numpy==1.22.* - numpy123: numpy==1.23.* - numpy124: numpy==1.24.* astropylts: astropy==5.0.* transformlts: asdf-transform-schemas==0.2.* @@ -48,7 +35,10 @@ extras = test alldeps: all commands_pre= - devdeps: pip install -U --pre --only-binary :all: -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy + numpydev: pip install -U --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy + numpydev: pip install -U --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple scipy + devdeps: pip install -U --pre -i https://pypi.anaconda.org/liberfa/simple pyerfa + devdeps: pip install -U --pre -i https://pypi.anaconda.org/astropy/simple astropy # Generate `requiremments-min.txt` oldestdeps: minimum_dependencies asdf-astropy --filename {envtmpdir}/requirements-min.txt