Exemple #1
0
    def _cls_scale(cls, scale: str) -> "Type[TimeArray]":
        """Check that scale is valid and return corresponding type"""
        if scale not in cls._scales():
            scales = ", ".join(sorted(cls._scales()))
            raise exceptions.UnknownSystemError(
                f"Scale {scale!r} unknown. Use one of {scales}")

        return cls._scales()[scale]
Exemple #2
0
def get(ellipsoid: str) -> "Ellipsoid":
    """Get an ellipsoid by name"""
    try:
        return _ELLIPSOIDS[ellipsoid]
    except KeyError:
        ellipsoids = ", ".join(sorted(_ELLIPSOIDS))
        raise exceptions.UnknownSystemError(
            f"Ellipsoid {ellipsoid!r} unknown. Use one of {ellipsoids}")
Exemple #3
0
    def __new__(cls, val, fmt, val2=None, _jd1=None, _jd2=None):
        """Create a new TimeArray"""
        if cls.scale is None:
            raise ValueError(
                f"{cls.__name__} cannot be instantiated. Use Time(val=..., scale={cls.scale!r}) instead"
            )

        if fmt not in cls._formats():
            formats = ", ".join(cls._formats())
            raise exceptions.UnknownSystemError(
                f"Format {fmt!r} unknown. Use one of {formats}")

        # Convert to numpy array and read format
        fmt_values = cls._formats()[fmt](val, val2, cls.scale)

        val = np.asarray(val)
        if val2 is not None:
            val2 = np.asarray(val2)
            if val2.shape != val.shape:
                raise ValueError(
                    f"'val2' must have the same shape as 'val': {val.shape}")

            if val2.ndim == 0:
                val2 = val2.item()

        if val.ndim == 0:
            val = val.item()

        # Store values on array
        obj = np.asarray(fmt_values.value).view(cls)
        jd1 = fmt_values.jd1 if _jd1 is None else _jd1
        jd2 = fmt_values.jd2 if _jd2 is None else _jd2

        # Validate shape
        fmt_ndim = cls._formats()[fmt].ndim
        if obj.ndim > fmt_ndim:
            raise ValueError(
                f"{type(self).__name__!r} must be a {fmt_ndim - 1} or {fmt_ndim}-dimensional array for format type {obj_fmt}"
            )

        # Freeze
        if isinstance(jd1, np.ndarray):
            jd1.flags.writeable = False
        if isinstance(jd2, np.ndarray):
            jd2.flags.writeable = False
        super(TimeBase, obj).__setattr__("fmt", fmt)
        super(TimeBase, obj).__setattr__("jd1", jd1)
        super(TimeBase, obj).__setattr__("jd2", jd2)

        if isinstance(obj, np.ndarray):
            obj.flags.writeable = False
        return obj
def get(model: str) -> "PlateMotionModel":
    """Get a tectonic plate motion model by name
    
    Args:
        model: Plate motion model name
        
    Returns:
        Instance of PlateMotionModel dataclass
    """
    try:
        return replace(_PLATE_MOTION_MODELS[model])   # Make a copy of PlateMotionModel object
    except KeyError:
        models = ", ".join(sorted(_PLATE_MOTION_MODELS))
        raise exceptions.UnknownSystemError(f"Tectonic plate model {model!r} unknown. Use one of {models}")
Exemple #5
0
    def __init__(self, plate: str, model: str = "itrf2014") -> None:
        """Initilialize PlateMotion object by defining tectonic plate
        
        Args:
            plate: Name of tectonic plate
            model: Name of plate motion model
        """
        model_ = plate_motion_models.get(model)
        if not plate in model_.plates:
            raise exceptions.UnknownSystemError(
                f"Tectonic plate {plate!r} unknown in plate motion model {model!r}. "
                f"Use one of {model_.plates}")

        self.plate = plate
        self.model = model
        self.pole = model_.get_pole(plate, unit="radian per year")
Exemple #6
0
    def create(val: np.ndarray, system: str,
               **dir_args: Any) -> "DirectionArray":
        """Factory for creating DirectionArrays for different systems

        See each direction class for exact optional parameters.

        Args:
            val:       Array of position values.
            system:    Name of direction system.
            dir_args:  Additional arguments used to create the DirectionArray.

        Returns:
            Array with positions in the given system.
        """
        if system not in _SYSTEMS:
            systems = ", ".join(_SYSTEMS)
            raise exceptions.UnknownSystemError(
                f"System {system!r} unknown. Use one of {systems}")

        return _SYSTEMS[system](val, **dir_args)
    def get_pole(self, plate: str, unit: Union[None, str] = None ) -> "RotationPole":
        """Get rotation pole object for given tectonic plate
        
        Args:
            plate: Name of tectonic plate (e.g. eura)
            model: Plate motion model name
            unit:  Define unit of rotation pole (e.g. 'radian per year', 'milliarcsecond per year')
            
        Returns:
            Instance of RotationPole dataclass for chosen tectonic plate
        """
        try:
            pole = replace(self.poles[plate])  # Make a copy of RotationPole object
        except KeyError:
            plates = ", ".join(sorted(self.poles.keys()))
            raise exceptions.UnknownSystemError(f"Tectonic plate {plate!r} unknown in plate motion model {self.name}. Use one of {plates}")

        if unit:
            for entry in ["wx", "wy", "wz", "dwx", "dwy", "dwz"]:
                setattr(pole, entry, getattr(pole, entry) * Unit(pole.unit).to(unit).m)
            pole.unit = unit
            
        return pole
Exemple #8
0
    def to_system(self, system: str) -> "PosDeltaBase":
        """Convert to a different system

        Args:
            system:  Name of new system.

        Returns:
            PosDeltaBase representing the same positions or position deltas in the new system.
        """
        # Don't convert if not necessary
        if system == self.system:
            return self

        # Raise error for unknown systems
        if system not in _SYSTEMS:
            systems = ", ".join(_SYSTEMS)
            raise exceptions.UnknownSystemError(
                f"System {system!r} unknown. Use one of {systems}")

        if system in self._cache:
            return self._cache[system]

        # Convert to new system
        hop = (self.system, system)
        if hop in _CONVERSIONS:
            self._cache[system] = _SYSTEMS[system].convert_to(
                self, _CONVERSIONS[hop])
            return self._cache[system]

        if hop not in _CONVERSION_HOPS:
            _CONVERSION_HOPS[self.cls_name][hop] = _find_conversion_hops(hop)

        val = self
        for one_hop in _CONVERSION_HOPS[hop]:
            val = _SYSTEMS[one_hop[-1]].convert_to(val, _CONVERSIONS[one_hop])
            self._cache[one_hop[-1]] = val
        return val
Exemple #9
0
    def to_scale(self, scale: str) -> "TimeArray":
        """Convert time to a different scale

        Returns a new TimeArray with the same time in the new scale.

        Args:
            scale:  Name of new scale.

        Returns:
            TimeArray representing the same times in the new scale.
        """
        # Don't convert if not necessary
        if scale == self.scale:
            return self

        # Raise error for unknown scales
        if scale not in self._scales():
            scales = ", ".join(self._scales())
            raise exceptions.UnknownSystemError(
                f"Scale {scale!r} unknown. Use one of {scales}")

        # Convert to new scale
        hop = (self.scale, scale)
        if hop in _CONVERSIONS:
            jd1, jd2 = _CONVERSIONS[hop](self)
            return self._scales()[scale].from_jds(jd1, jd2, self.fmt)

        if hop not in _CONVERSION_HOPS:
            _CONVERSION_HOPS[hop] = _find_conversion_hops(hop)

        converted_time = self
        for one_hop in _CONVERSION_HOPS[hop]:
            jd1, jd2 = _CONVERSIONS[one_hop](converted_time)
            converted_time = self._scales()[one_hop[-1]].from_jds(
                jd1, jd2, self.fmt)
        return converted_time