Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Coordinate Frames #567

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,13 @@ repos:
- id: ruff
args: ["--fix", "--show-fixes"]
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.15.0"
hooks:
- id: mypy
files: gwcs
args: []
additional_dependencies: # add dependencies for mypy to pull information from
- numpy>=2
- astropy>=7
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

- Fix API issue with ``wcs.numerical_inverse``. [#565]

- Bugfix for ``__call__`` and ``invert`` incorrectly handling units when involving
"parameterless" transforms. [#562]

- Fix bug where "vector" (shape (n,) not shape (1, n)) arrays would loose all their entries except the
first if ``with_units=True`` was used. [#563]

0.24.0 (2025-02-04)
-------------------

Expand Down
58 changes: 58 additions & 0 deletions gwcs/_typing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from __future__ import annotations

from fractions import Fraction
from typing import TypeAlias

import numpy as np
import numpy.typing as npt
from astropy.coordinates import (
BaseCoordinateFrame,
SkyCoord,
SpectralCoord,
StokesCoord,
)
from astropy.modeling.bounding_box import CompoundBoundingBox, ModelBoundingBox
from astropy.time import Time
from astropy.units import Quantity

__all__ = [
"AxisPhysicalType",
"AxisPhysicalTypes",
"BoundingBox",
"Bounds",
"HighLevelObject",
"HighLevelObjects",
"Interval",
"LowLevelArrays",
"LowLevelUnitArrays",
"LowLevelUnitValue",
"LowLevelValue",
"OutputLowLevelArray",
"Real",
]

Real: TypeAlias = int | float | Fraction | np.integer | np.floating

Interval: TypeAlias = tuple[Real, Real]
Bounds: TypeAlias = tuple[Interval, ...] | None

BoundingBox: TypeAlias = ModelBoundingBox | CompoundBoundingBox | None

# This is to represent a single value from a low-level function.
LowLevelValue: TypeAlias = Real | npt.NDArray[np.number]
# Handle when units are a possibility. Not all functions allow units in/out
LowLevelUnitValue: TypeAlias = LowLevelValue | Quantity

# This is to represent all the values together for a single low-level function.
LowLevelArrays: TypeAlias = tuple[LowLevelValue, ...] | LowLevelValue
LowLevelUnitArrays: TypeAlias = tuple[LowLevelUnitValue, ...]

# This is to represent a general array output from a low-level function.
# Due to the fact 1D outputs are returned as a single value, rather than a tuple.
OutputLowLevelArray: TypeAlias = LowLevelValue | LowLevelArrays

HighLevelObject: TypeAlias = Time | SkyCoord | SpectralCoord | StokesCoord | Quantity
HighLevelObjects: TypeAlias = tuple[HighLevelObject, ...] | HighLevelObject

AxisPhysicalType: TypeAlias = str | BaseCoordinateFrame
AxisPhysicalTypes: TypeAlias = tuple[str | BaseCoordinateFrame, ...]
49 changes: 48 additions & 1 deletion gwcs/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,60 @@

"""

from collections.abc import Callable
from typing import Any, NamedTuple, TypeAlias

import astropy.units as u
from astropy.modeling import separable
from astropy.wcs.wcsapi import BaseLowLevelWCS, HighLevelWCSMixin

from gwcs import utils

__all__ = ["GWCSAPIMixin"]
__all__ = [
"GWCSAPIMixin",
"WorldAxisClass",
"WorldAxisClasses",
"WorldAxisComponent",
"WorldAxisComponents",
"WorldAxisConverterClass",
]


class WorldAxisClass(NamedTuple):
"""
Named tuple for the world_axis_object_classes WCS property
"""

object_type: type | str
args: tuple[int | None, ...]
kwargs: dict[str, Any]


class WorldAxisConverterClass(NamedTuple):
"""
Named tuple for the world_axis_object_classes WCS property, which have a converter
"""

object_type: type | str
args: tuple[int | None, ...]
kwargs: dict[str, Any]
converter: Callable[..., Any] | None = None


WorldAxisClasses: TypeAlias = dict[str | int, WorldAxisClass | WorldAxisConverterClass]


class WorldAxisComponent(NamedTuple):
"""
Named tuple for the world_axis_object_components WCS property
"""

name: str
key: str | int
property_name: str | Callable[[Any], Any]


WorldAxisComponents: TypeAlias = list[WorldAxisComponent]


class GWCSAPIMixin(BaseLowLevelWCS, HighLevelWCSMixin):
Expand Down
Loading
Loading