diff --git a/gwcs/coordinate_frames.py b/gwcs/coordinate_frames.py index fcf329e0..f4c4f9e4 100644 --- a/gwcs/coordinate_frames.py +++ b/gwcs/coordinate_frames.py @@ -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): @@ -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) @@ -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): @@ -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': ( @@ -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': ( @@ -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 = ( @@ -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): @@ -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)])