Skip to content

Commit

Permalink
Put axes_phyiscal_types logic in subclasses
Browse files Browse the repository at this point in the history
This moves the logic for the default physical types into the subclasses
rather than the base class.
  • Loading branch information
Cadair committed Jun 15, 2023
1 parent e7056a9 commit 297342d
Showing 1 changed file with 67 additions and 49 deletions.
116 changes: 67 additions & 49 deletions gwcs/coordinate_frames.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,12 @@ def __init__(self, naxes, axes_type, axes_order, reference_frame=None,
raise ValueError("Length of axes_order does not match number of axes.")

super(CoordinateFrame, self).__init__()
# _axis_physical_types holds any user supplied physical types
self._axis_physical_types = self._set_axis_physical_types(axis_physical_types)

def _set_axis_physical_types(self, pht=None):
def _set_axis_physical_types(self, pht):
"""
Set the physical type of the coordinate axes using VO UCD1+ v1.23 definitions.
"""
if pht is not None:
if isinstance(pht, str):
Expand All @@ -171,49 +171,6 @@ def _set_axis_physical_types(self, pht=None):
else:
ph_type.append(axt)

elif isinstance(self, CelestialFrame):
if isinstance(self.reference_frame, coord.Galactic):
ph_type = "pos.galactic.lon", "pos.galactic.lat"
elif isinstance(self.reference_frame, (coord.GeocentricTrueEcliptic,
coord.GCRS,
coord.PrecessedGeocentric)):
ph_type = "pos.bodyrc.lon", "pos.bodyrc.lat"
elif isinstance(self.reference_frame, coord.builtin_frames.BaseRADecFrame):
ph_type = "pos.eq.ra", "pos.eq.dec"
elif isinstance(self.reference_frame, coord.builtin_frames.BaseEclipticFrame):
ph_type = "pos.ecliptic.lon", "pos.ecliptic.lat"
else:
ph_type = tuple("custom:{}".format(t) for t in self.axes_names)

elif isinstance(self, SpectralFrame):
if self.unit[0].physical_type == "frequency":
ph_type = ("em.freq",)
elif self.unit[0].physical_type == "length":
ph_type = ("em.wl",)
elif self.unit[0].physical_type == "energy":
ph_type = ("em.energy",)
elif self.unit[0].physical_type == "speed":
ph_type = ("spect.dopplerVeloc",)
logging.warning("Physical type may be ambiguous. Consider "
"setting the physical type explicitly as "
"either 'spect.dopplerVeloc.optical' or "
"'spect.dopplerVeloc.radio'.")
else:
ph_type = ("custom:{}".format(self.unit[0].physical_type),)

elif isinstance(self, TemporalFrame):
ph_type = ("time",)

elif isinstance(self, Frame2D):
if all(self.axes_names):
ph_type = self.axes_names
else:
ph_type = self.axes_type
ph_type = tuple("custom:{}".format(t) for t in ph_type)

else:
ph_type = tuple("custom:{}".format(t) for t in self.axes_type)

validate_physical_types(ph_type)
return tuple(ph_type)

Expand Down Expand Up @@ -296,9 +253,22 @@ def coordinate_to_quantity(self, *coords):
return coords[0]
return coords

@property
def _default_axis_physical_types(self):
"""
The default physical types to use for this frame if none are specified
by the user.
"""
return tuple("custom:{}".format(t) for t in self.axes_type)

@property
def axis_physical_types(self):
return self._axis_physical_types
"""
The axis physical types for this frame.
These physical types are the types in frame order, not transform order.
"""
return self._axis_physical_types or self._default_axis_physical_types

@property
def _world_axis_object_classes(self):
Expand Down Expand Up @@ -360,6 +330,21 @@ def __init__(self, axes_order=None, reference_frame=None,
axes_names=axes_names,
name=name, axis_physical_types=axis_physical_types)

@property
def _default_axis_physical_types(self):
if isinstance(self.reference_frame, coord.Galactic):
return "pos.galactic.lon", "pos.galactic.lat"
elif isinstance(self.reference_frame, (coord.GeocentricTrueEcliptic,
coord.GCRS,
coord.PrecessedGeocentric)):
return "pos.bodyrc.lon", "pos.bodyrc.lat"
elif isinstance(self.reference_frame, coord.builtin_frames.BaseRADecFrame):
return "pos.eq.ra", "pos.eq.dec"
elif isinstance(self.reference_frame, coord.builtin_frames.BaseEclipticFrame):
return "pos.ecliptic.lon", "pos.ecliptic.lat"
else:
return tuple("custom:{}".format(t) for t in self.axes_names)

@property
def _world_axis_object_classes(self):
return {'celestial': (
Expand Down Expand Up @@ -446,6 +431,23 @@ def __init__(self, axes_order=(0,), reference_frame=None, unit=None,
reference_position=reference_position,
axis_physical_types=axis_physical_types)

@property
def _default_axis_physical_types(self):
if self.unit[0].physical_type == "frequency":
return ("em.freq",)
elif self.unit[0].physical_type == "length":
return ("em.wl",)
elif self.unit[0].physical_type == "energy":
return ("em.energy",)
elif self.unit[0].physical_type == "speed":
return ("spect.dopplerVeloc",)
logging.warning("Physical type may be ambiguous. Consider "
"setting the physical type explicitly as "
"either 'spect.dopplerVeloc.optical' or "
"'spect.dopplerVeloc.radio'.")
else:
return ("custom:{}".format(self.unit[0].physical_type),)

@property
def _world_axis_object_classes(self):
return {'spectral': (
Expand Down Expand Up @@ -510,6 +512,10 @@ def __init__(self, reference_frame, unit=None, axes_order=(0,),
except AttributeError:
pass

@property
def _default_axis_physical_types(self):
return ("time",)

@property
def _world_axis_object_classes(self):
comp = (
Expand Down Expand Up @@ -716,10 +722,14 @@ class StokesFrame(CoordinateFrame):
A dimension in the data that corresponds to this axis.
"""

def __init__(self, axes_order=(0,), name=None):
def __init__(self, axes_order=(0,), axes_names=("stokes",), name=None, axis_physical_types=None):
super(StokesFrame, self).__init__(1, ["STOKES"], axes_order, name=name,
axes_names=("stokes",), unit=u.one,
axis_physical_types="phys.polarization.stokes")
axes_names=axes_names, unit=u.one,
axis_physical_types=axis_physical_types)

@property
def _default_axis_physical_types(self):
return ("phys.polarization.stokes",)

@property
def _world_axis_object_classes(self):
Expand Down Expand Up @@ -771,6 +781,14 @@ def __init__(self, axes_order=(0, 1), unit=(u.pix, u.pix), axes_names=('x', 'y')
axes_names=axes_names, unit=unit,
axis_physical_types=axis_physical_types)

@property
def _default_axis_physical_types(self):
if all(self.axes_names):
ph_type = self.axes_names
else:
ph_type = self.axes_type
return tuple("custom:{}".format(t) for t in ph_type)

def coordinates(self, *args):
args = [args[i] for i in self.axes_order]
coo = tuple([arg * un for arg, un in zip(args, self.unit)])
Expand Down

0 comments on commit 297342d

Please sign in to comment.