PKҊL%OOmidgard/__init__.py"""Midgard, the Python Geodesy library Midgard is a collection of useful Python utilities used by the Geodetic institute at the Norwegian Mapping Authority (Kartverket). Although some of these are geodesy-specific, many are also useful in more general settings. Note: Midgard is still in pre-alpha status. Its functionality will change, and it should not be depended on in any production-like setting. Midgard comes organized into different subpackages: {subpackages} Look for help inside each subpackage: >>> from midgard import subpackage >>> help(subpackage) Current maintainers: -------------------- {maintainers} """ # Standard library imports from datetime import date as _date from collections import namedtuple as _namedtuple from pathlib import Path as _Path # Version of Midgard. # # This is automatically set using the bumpversion tool __version__ = "0.1.2" # Authors of Midgard. _Author = _namedtuple("_Author", ["name", "email", "start", "end"]) _AUTHORS = [_Author("Geir Arne Hjelle", "geir.arne.hjelle@kartverket.no", _date.min, _date.max)] __author__ = ", ".join(a.name for a in _AUTHORS if a.start < _date.today() < a.end) __contact__ = ", ".join(a.email for a in _AUTHORS if a.start < _date.today() < a.end) # Copyleft of the library __copyright__ = f"2018 - {_date.today().year} Norwegian Mapping Authority" # Update doc with info about subpackages and maintainers def _update_doc(doc): """Add information to doc-string Args: doc (str): The doc-string to update. Returns: str: The updated doc-string """ # Subpackages subpackage_paths = _Path(__file__).parent.iterdir() subpackage_list = [p.name for p in subpackage_paths if p.is_dir() and not p.name.startswith("_")] subpackages = "\n".join(f"+ {p}" for p in subpackage_list) # Maintainers maintainer_list = [f"+ {a.name} <{a.email}>" for a in _AUTHORS if a.start < _date.today() < a.end] maintainers = "\n".join(maintainer_list) # Add to doc-string return doc.format(subpackages=subpackages, maintainers=maintainers) __doc__ = _update_doc(__doc__) PK`ZL8)hhmidgard/collections/enums.py"""Framework for working with enumerations Description: ------------ Custom enumerations used for structured names. """ # Midgard imports from midgard.dev import exceptions # Dictionary of Enumerations. Populated by the @register_enum-decorators. _ENUMS = dict() def get_enum(name=None): """Return a named Enumeration Names are defined by the @register_enum-decorator. If the name-parameter is not given, the function will raise an UnknownEnumError and list the available enumerations. Args: name (String): Name used for Enumeration. Returns: Enum: Enumeration with the given name. """ try: return _ENUMS[name] except KeyError: valid_enums = ", ".join(e for e in _ENUMS) raise exceptions.UnknownEnumError( f"Enumeration '{name}' is not defined. Available enumerations are {valid_enums}." ) from None def get_value(name, value): """Return the value of a named Enumeration Names are defined by the @register_enum-decorator. Args: name (String): Name used for Enumeration. value (String): Value of Enumeration. Returns: Enum: Value of enumeration with the given name. """ try: return get_enum(name)[value] except KeyError: valid_values = ", ".join(v.name for v in get_enum(name)) raise ValueError( f"Value '{value}' is not valid for a {name}-enumeration. Valid values are {valid_values}." ) from None def register_enum(name): """Register a named Enumeration This allows for getting Enumerations with the get_enum-function. Args: name (String): Name used for Enumeration. Returns: Decorator: Decorator that registers an Enumeration. """ def register_decorator(func): _ENUMS[name] = func return func return register_decorator PKwL&midgard/collections/dataset/dataset.pyPKzL$midgard/collections/dataset/table.pyPK첐Lmidgard/config/config.pyPKҲLmidgard/config/constant.pyPKԲLmidgard/config/unit.pyPKLmidgard/coords/position.pyPK=Lmidgard/coords/time.pyPK,Lmidgard/dev/__init__.pyPKαLmidgard/dev/cache.pyPKL~>'+ + midgard/dev/console.py"""Simpler dealing with the console Description: ------------ Utilities for using the console. Mainly wrappers around other libraries to make them easier and more intuitive to use. Size of console: The two functions `lines()` and `columns()` report the current size of the console. Textwrapping: The function `fill()` can be used to rewrap a text-string so that it fits inside the console. Color: The sub-module `color` can be used to set the foreground and background colors. Note that the color functionality depends on the external package `colorama`. If `colorama` is not installed, color gracefully falls back to not showing any color. Examples: --------- >>> from midgard.lib import console >>> print(console.columns()) 86 >>> print(console.fill(a_very_long_string)) Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tempus eleifend feugiat. Maecenas vitae posuere metus. Sed sit amet fermentum velit. Aenean vitae turpis at risus sollicitudin fringilla in in nisi. Maecenas vitae ante libero. Aenean ut eros consequat, ornare erat at, tempus arcu. Suspendisse velit leo, eleifend eget mi non, vehicula ultricies erat. Vestibulum id nisi eget nisl venenatis dignissim. Duis cursus quam dui, vel hendrerit nibh lacinia id. >>> print(console.color.Fore.YELLOW + console.color.Back.BLUE + 'I am YELLOW text on a BLUE background!') I am YELLOW text on a BLUE background! """ # Standard library imports import shutil import textwrap from typing import Any, Optional # Midgard imports from midgard.dev import optional # Use colorama for coloring in the console, graceful fallback to no color if colorama is not installed _empty_string = optional.EmptyStringMock("_empty_string") color = optional.optional_import( "colorama", attrs=dict(init=lambda **_: None, Back=_empty_string, Fore=_empty_string, Style=_empty_string) ) color.init(autoreset=True) def lines() -> int: """The height of the console Returns: The heigth of the console in characters. """ return shutil.get_terminal_size().lines def columns() -> int: """The width of the console Returns: The width of the console in characters. """ return shutil.get_terminal_size().columns def fill(text: str, *, width: Optional[int] = None, hanging: Optional[int] = None, **tw_args: Any) -> str: """Wrapper around textwrap.fill The `tw_args` are passed on to textwrap.fill. See textwrap.TextWrapper for available keyword arguments. The default value for `width` is console.columns(), while the new argument `hanging`, if defined, will try to set (although not override) the textwrap-arguments `initial_indent` and `subsequent_indent` to create a hanging indent (no indent on the first line) of `hanging` spaces. Args: text (String): Text that will be wrapped. width (Integer): The maximum width (in characters) of wrapped lines. hanging (Integer): Number of characters used for hanging indent. tw_args: Arguments passed on to `textwrap.fill`. Returns: String: Wrapped string. """ width = columns() if width is None else width if hanging is not None: tw_args.setdefault("initial_indent", "") tw_args.setdefault("subsequent_indent", " " * hanging) return textwrap.fill(text, width=width, **tw_args) PK5Lmidgard/dev/exceptions.py"""Definition of Midgard-specific exceptions Description: ------------ Custom exceptions used by Midgard for more specific error messages and handling. """ class MidgardException(Exception): pass class MidgardExit(SystemExit, MidgardException): pass class InitializationError(MidgardException): pass class FieldExistsError(MidgardException): pass class FieldDoesNotExistError(MidgardException): pass class MissingDataError(MidgardException): pass class UnknownEnumError(MidgardException): pass class UnknownPluginError(MidgardException): pass class UnitError(MidgardException): pass PKuLmidgard/dev/interactive.pyPK4[L/8<<midgard/dev/library.py"""Python wrapper around C-libraries Description: ------------ Loads a C-library. If a library is missing, a mock library is returned. If this mock is used for anything, a warning will be printed. This is done to avoid dependencies to all the C/C++-libraries for Python programs only using some of them. """ # Standard library imports import ctypes as c from ctypes import util as c_util import sys def load_name(library_name, func_specs=None, name_patterns=None): """Load the given shared C-library See `load_path` for an explanation of the `func_specs` and `name_patterns`-arguments. Args: library_name (String): The name of the library. func_specs (Dict): Specification of types in lib (see load_path). name_patterns (List): Name mangling patterns (see load_path). Returns: ctypes.CDLL: Representation of the shared library. """ library_path = c_util.find_library(library_name) return load_path(library_path, func_specs=func_specs, name_patterns=name_patterns) def load_path(library_path, func_specs=None, name_patterns=None): """Load the given shared C-library The optional func_specs-dictionary can be used to specify argument and return types of functions in the library (see the ctypes documentation for information about argtypes and restype). The dictionary should be on the form:: func_spec = {'func_1': dict(func_name='name_of_func_1_in_lib', argtypes=[ ... argtypes of func_1 ... ], restype=... restype of func_1 ...), 'func_2': ... } If the library is not found, a mock library is returned instead. The mock library will print a warning if it is used. For some libraries, name mangling is used and this might be different depending on operating system and how the library is compiled. For instance, in a Fortran library the function `Test` might be represented as `__Test` on a Windows system and `test_` (with lower-case `t`) on a Linux system. This can be handled by providing a list of possible patterns. The above example can be handled by:: name_patterns = ('__{func_name}', '{func_name_lower}_') In this case, each function in func_specs is looked up by testing each pattern in turn until a match is found. Args: library_path (String): The path to the library. func_specs (Dict): Specification of types in library (see above). name_patterns (List): Name mangling patterns (see above). Returns: ctypes.CDLL: Representation of the shared library. """ library_handle = c.cdll.LoadLibrary(library_path) # Return a Mock object if the library is not found if library_handle._name is None: mock = SimpleMock(name=library_path) return mock # Handle name mangling if name_patterns is None: def mangled_name(name): return name else: def mangled_name(name): for pattern in name_patterns: full_name = pattern.format(func_name=name, func_name_lower=name.lower()) if hasattr(library_handle, full_name): return full_name return name # Set argument and return types on functions if func_specs: for name, spec in func_specs.items(): if "func_name" in spec: func_name = mangled_name(spec["func_name"]) else: func_name = mangled_name(name) func = getattr(library_handle, func_name) delattr(library_handle, func_name) if "argtypes" in spec: func.argtypes = spec["argtypes"] if "restype" in spec: func.restype = spec["restype"] setattr(library_handle, name, func) return library_handle class SimpleMock: """Class that can stand in for any other object The SimpleMock is used to stand in for any library that can not be imported. The mock object simply returns itself whenever it is called, or any attributes are looked up on the object. This is done, to avoid ImportErrors when a library is imported, but never used (typically because a plugin is loaded but never called). Instead the ImportError is raised when the SimpleMock is used in any way. The ImportError will only be raised once for any SimpleMock-object (which is only important if the ImportError is caught and the program carries on). """ def __init__(self, name, raise_error=True): """Initialize SimpleMock object Args: name (String): Name of SimpleMock-object. raise_error (Bool): Should ImportError be raised when using object. """ self._name = name self._children = dict() self._raise_error = raise_error def _raise_import_error(self): """Raise an import error when the SimpleMock object is used The ImportError is only raised the first time the object is used. """ # Only raise the error once if self._raise_error: self._raise_error = False else: return # Find calling function caller = sys._getframe() while caller.f_code.co_filename == __file__: caller = caller.f_back func_name = caller.f_code.co_name line_no = caller.f_lineno file_name = caller.f_code.co_filename # Raise ImportError with a helpful message raise ImportError( "The library '{}' is not installed, but is used by '{}' on line {} of {}" "".format(self._name, func_name, line_no, file_name) ) def __call__(self, *args, **kwargs): """Return the same SimpleMock-object when it is called An ImportError is raised the first time the object is used. Returns: SimpleMock: Itself. """ self._raise_import_error() return self def __getattr__(self, key): """Create a child-SimpleMock-object and return it. The same child object is returned if the same attribute is gotten several times. An ImportError is raised the first time the SimpleMock-object is used. Additional errors are not raised for the children. Args: key (String): Name of attribute. Returns: SimpleMock: A child-SimpleMock-object. """ self._raise_import_error() if key not in self._children: self._children[key] = type(self)("{}.{}".format(self._name, key), raise_error=self._raise_error) setattr(self, key, self._children[key]) return self._children[key] def __repr__(self): """String representation of the SimpleMock-object Returns: String: Simple representation of the SimpleMock-object. """ return "{}('{}')".format(self.__class__.__name__, self._name) def __str__(self): """Convert to the empty string Returns: String: An empty string. """ return "" PKױLmidgard/dev/log.pyPKLeemidgard/dev/optional.py"""Midgard library module for handling optional dependencies Description: ------------ Import dependencies that are only necessary for specific parts of Midgard. Using this module will delay raising an ImportError until the dependency is actually used. This means that if one for instance only wants to run a GNSS analysis (or only use a Rinex-parser) installing special libraries only used for VLBI is not necessary. Examples: --------- The optional import is typically used as follows:: from midgard.lib import optional netCDF4 = optional.optional_import('netCDF4') """ # Standard library imports import importlib import sys from types import ModuleType from typing import Any, Dict, List, Optional, Union class SimpleMock: """Class that can stand in for any other object The SimpleMock is used to stand in for any library that can not be imported. The mock object simply returns itself whenever it is called, or any attributes are looked up on the object. This is done, to avoid ImportErrors when a library is imported, but never used (for instance if a plugin is loaded but never called). Instead the ImportError is raised when the SimpleMock is used in any way. The ImportError will only be raised once for any SimpleMock-object (which is only important if the ImportError is caught and the program carries on). The exception is if any attributes (`attrs`) are explicitly defined on the mock. No exception is raised if those attributes are looked up. """ def __init__(self, name: str, raise_error: bool = True, attrs: Optional[Dict[str, Any]] = None) -> None: """Initialize SimpleMock object Args: name: Name of SimpleMock-object. Used for string representation and when raising Errors. raise_error: Whether ImportError should be raised when object is used. attrs: Attributes that should be added to the SimpleMock. """ self._name = name self._children: Dict[str, "SimpleMock"] = dict() self._raise_error = raise_error self._attrs = attrs if attrs is not None: for name, attr in attrs.items(): setattr(self, name, attr) def _raise_import_error(self) -> None: """Raise an import error when the SimpleMock object is used The ImportError is only raised the first time the object is used. """ # Only raise the error once if self._raise_error: self._raise_error = False else: return # Find calling function caller = sys._getframe() while caller.f_code.co_filename == __file__: caller = caller.f_back func_name = caller.f_code.co_name line_num = caller.f_lineno file_name = caller.f_code.co_filename # Raise ImportError with a helpful message raise ImportError( f"The module '{self._name}' is not installed, " f"but is used by '{func_name}' on line {line_num} of {file_name}" ) def __call__(self, *args: Any, **kwargs: Any) -> "SimpleMock": """Return the same SimpleMock-object when it is called An ImportError is raised the first time the object is used. Returns: Itself. """ self._raise_import_error() return self def __getattr__(self, key: str) -> Any: """Create a child-SimpleMock-object and return it. The same child object is returned if the same attribute is gotten several times. An ImportError is raised the first time the SimpleMock-object is used. Additional errors are not raised for the children. Args: key: Name of attribute. Returns: A child-SimpleMock-object. """ self._raise_import_error() if key not in self._children: child_name = f"{self._name}.{key}" self._children[key] = type(self)(child_name, raise_error=self._raise_error, attrs=self._attrs) setattr(self, key, self._children[key]) return self._children[key] def __repr__(self) -> str: """String representation of the SimpleMock-object Returns: Simple string representation of the SimpleMock-object. """ return f"{self.__class__.__name__}('{self._name}')" class EmptyStringMock(SimpleMock): """A mock object whose properties are all empty strings """ def __getattr__(self, key: str) -> str: """All attributes are empty strings. Args: key: Name of attribute. Returns: An empty string. """ return "" def optional_import( module_name: str, raise_error: bool = True, mock_cls: type = SimpleMock, attrs: Optional[Dict[str, Any]] = None ) -> Union[Any, SimpleMock]: # TODO: Should be typed types.ModuleType? but causes typing errors """Try to import an optional module If the module does not exist, a SimpleMock-object is returned instead. If this SimpleMock-object is later used, an ImportError will be raised then (if `raise_error` is True, which is default). Args: module_name: Name of module to import. raise_error: Whether an ImportError should be raised if the module does not exist, but is used. attrs: Attributes that should be added to the SimpleMock used if the module does not exist. Returns: Imported module object, or a SimpleMock-object if the module can not be imported. """ try: return importlib.import_module(module_name) except ImportError: return mock_cls(module_name, raise_error=raise_error, attrs=attrs) PK᱐Lmidgard/dev/plugins.pyPK豐Lmidgard/dev/profiler.pyPKLmidgard/dev/timer.pyPKLmidgard/dev/util.pyPKZLnOmidgard/files/dates.py"""Convenience functions for working with dates Description: ------------ Formats and converters that can be used for convenience and consistency. """ # Formats that can be passed to datetime.strftime, see http://strftime.org/ FMT_date = "%Y-%m-%d" FMT_datetime = "%Y-%m-%d %H:%M:%S" FMT_dt_file = "%Y%m%d-%H%M%S" def date_vars(date): """Construct a dict of date variables From a given date, construct a dict containing all relevant date variables. This dict can be used to for instance replace variables in file names. Examples: >>> from datetime import date >>> date_vars = date_vars(date(2009, 11, 2)) >>> sorted(date_vars.items()) # doctest: +NORMALIZE_WHITESPACE [('MMM', 'NOV'), ('ce', '20'), ('d', '2'), ('dd', '02'), ('dow', '1'), ('doy', '306'), ('gpsweek', '1556'), ('m', '11'), ('mm', '11'), ('mmm', 'nov'), ('yy', '09'), ('yyyy', '2009')] Args: date (Date/Datetime): The date. Returns: Dict: Dictionary with date variables for the given date. """ if date is None: return dict() # Create the dict of date variables return dict( yyyy=date.strftime("%Y"), ce=date.strftime("%Y")[:2], yy=date.strftime("%y"), m=str(date.month), mm=date.strftime("%m"), mmm=date.strftime("%b").lower(), MMM=date.strftime("%b").upper(), d=str(date.day), dd=date.strftime("%d"), doy=date.strftime("%j"), dow=date.strftime("%w"), ) PKƱLmidgard/files/dependencies.pyPKLmidgard/files/files.pyPKLmidgard/math/__init__.pyPKFL i++midgard/math/interpolation.py"""Methods for interpolating in numpy arrays Description: ------------ Different interpolation methods are decorated with `@register_interpolator` and will then become available for use as `kind` in `interpolate` and `moving_window`. Example: -------- >>> x = np.linspace(-1, 1, 11) >>> y = x**3 - x >>> y array([ 0. , 0.288, 0.384, 0.336, 0.192, 0. , -0.192, -0.336, -0.384, -0.288, 0. ]) >>> x_new = np.linspace(-0.8, 0.8, 11) >>> interpolation.interpolate(x, y, x_new, kind='cubic') array([ 0.288, 0.378, 0.369, 0.287, 0.156, -0. , -0.156, -0.287, -0.369, -0.378, -0.288]) Developer info: --------------- To add your own interpolators, you can simply decorate your interpolator functions with `@register_interpolator`. Your interpolator function should have the signature (x: np.ndarray, y: np.ndarray) -> Callable For instance, the following would implement a terrible interpolation function that sets all values to zero: from midgard.math.interpolation import register_interpolator @register_interpolator def zero(x: np.ndarray, y: np.ndarray) -> Callable: def _zero(x_new: np.ndarray) -> np.ndarray: return np.zeros(y.shape) return _zero This function would then be available as an interpolator. For instance, one could do >>> interpolation.interpolate(x, y, x_new, kind='zero') array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) """ # System library imports from typing import Any, Callable, Dict, List # Third party imports import numpy as np import scipy.interpolate import scipy.misc # Midgard imports from midgard.dev import exceptions # Dictionary of Enumerations. Populated by the @register_enum-decorators. _INTERPOLATORS: Dict[str, Callable] = dict() def register_interpolator(func: Callable) -> Callable: """Register an interpolation function This function should be used as a @register_interpolator-decorator Args: func: Function that will be registered as an interpolator. Returns: Same function. """ name = func.__name__ _INTERPOLATORS[name] = func return func def interpolators() -> List[str]: """Return a list of available interpolators Returns: Names of available interpolators. """ return sorted(_INTERPOLATORS) def get_interpolator(name: str) -> Callable: """Return an interpolation function Interpolation functions are registered by the @register_interpolator-decorator. The name-parameter corresponds to the function name of the interpolator. Args: name: Name of interpolator. Returns: Interpolation function with the given name. """ try: return _INTERPOLATORS[name] except KeyError: interpolator_list = ", ".join(interpolators()) raise exceptions.UnknownPluginError( f"Interpolator '{name}' is not defined. Available interpolators are {interpolator_list}." ) from None def interpolate(x: np.ndarray, y: np.ndarray, x_new: np.ndarray, *, kind: str, **ipargs: Dict[str, Any]) -> np.ndarray: """Interpolate values from one x-array to another See `interpolators()` for a list of valid interpolators. Args: x: 1-dimensional array with original x-values. y: Array with original y-values. x_new: 1-dimensional array with new x-values. kind: Name of interpolator to use. ipargs: Keyword arguments passed on to the interpolator. Returns: Array of interpolated y-values. """ interpolator = get_interpolator(kind)(x, y, **ipargs) return interpolator(x_new) def interpolate_with_derivative( x: np.ndarray, y: np.ndarray, x_new: np.ndarray, *, kind: str, dx: float = 0.5, **ipargs: Dict[str, Any] ) -> np.ndarray: """Interpolate values from one x-array to another as well as find derivatives See `interpolators()` for a list of valid interpolators. Args: x: 1-dimensional array with original x-values. y: Array with original y-values. x_new: 1-dimensional array with new x-values. kind: Name of interpolator to use. dx: Values at x ± dx are used to determine derivative. ipargs: Keyword arguments passed on to the interpolator. Returns: Tuple with array of interpolated y-values and array of derivatives. """ interpolator = get_interpolator(kind)(x, y, **ipargs) y_new = interpolator(x_new) y_dot = scipy.misc.derivative(interpolator, x_new, dx=dx) return y_new, y_dot @register_interpolator def lagrange( x: np.ndarray, y: np.ndarray, *, window: int = 10, bounds_error: bool = True, assume_sorted: bool = False ) -> Callable: """Computes the lagrange polynomial passing through a certain set of points See https://en.wikipedia.org/wiki/Lagrange_polynomial Uses `window` of the original points to calculate the Lagrange polynomials. The window of points is chosen by finding the closest original point and essentially picking the `window // 2` indices on either side. Args: x: 1-dimensional array with original x-values. y: Array with original y-values. window: Number of points used in interpolation. bounds_error: If True, a ValueError is raised if extrapolation is attempted. assume_sorted: If True, x must be an array of monotonically increasing values. Returns: Lagrange interpolation function """ # Check input if window < 3: raise ValueError("The window should be at least 3") if window > len(x): raise ValueError(f"x and y arrays must have at least window={window} entries") if len(y) != len(x): raise ValueError("x and y arrays must be equal in length along the first axis.") if x.ndim != 1: raise ValueError("the x array must have exactly one dimension.") if y.ndim < 1: raise ValueError("the y array must have at least one dimension.") # Sort the input according to the x-array if not assume_sorted: sort_idxs = np.argsort(x) x, y = x[sort_idxs], y[sort_idxs] # Check that x values are monotonically increasing if not all(np.diff(x) > 0): raise ValueError("expected x to be a sorted array with unique values") # Rescale x values to avoid numerical instability _xm, _xs = x.mean(), x.std() x_scaled = (x - _xm) / _xs # Indices to use during calculation of polynomial values indices = np.eye(window) == 0 def _lagrange(x_new: np.ndarray) -> np.ndarray: """Interpolate using a Lagrange polynomial""" if x_new.min() < x.min(): raise ValueError("A value in x_new is below the interpolation range.") if x_new.max() > x.max(): raise ValueError("A value in x_new is above the interpolation range.") y_new = np.zeros(x_new.shape[:1] + y.shape[1:]) x_new_scaled = (x_new - _xm) / _xs # Figure out which points to use for the interpolation start_idxs = np.abs(x[:, None] - x_new[None, :]).argmin(axis=0) - window // 2 start_idxs[start_idxs < 0] = 0 start_idxs[start_idxs > len(x) - window] = len(x) - window # Interpolate for each unique set of interpolation points for idx in np.unique(start_idxs): y_idx = start_idxs == idx x_wd, y_wd = x_scaled[idx:idx + window], y[idx:idx + window] diff_x = np.subtract(*np.meshgrid(x_wd, x_wd)) + np.eye(window) r = np.array( [ np.prod((x_new_scaled[y_idx, None] - x_wd[idxs]) / diff_x[idxs, i], axis=1) for i, idxs in enumerate(indices) ] ) y_new[y_idx] = r.T @ y_wd return y_new return _lagrange @register_interpolator def linear(x: np.ndarray, y: np.ndarray, **ipargs: Dict[str, Any]) -> Callable: """Linear interpolation through the given points Uses the scipy.interpolate.interp1d function with kind='linear' behind the scenes. Args: x: 1-dimensional array with original x-values. y: Array with original y-values. ipargs: Keyword arguments passed on to the interp1d-interpolator. Returns: Linear interpolation function """ return scipy.interpolate.interp1d(x, y, kind="linear", **ipargs) @register_interpolator def cubic(x: np.ndarray, y: np.ndarray, **ipargs: Dict[str, Any]) -> Callable: """Cubic spline interpolation through the given points Uses the scipy.interpolate.interp1d function with kind='cubic' behind the scenes. Args: x: 1-dimensional array with original x-values. y: Array with original y-values. ipargs: Keyword arguments passed on to the interp1d-interpolator. Returns: Cubic spline interpolation function """ return scipy.interpolate.interp1d(x, y, kind="cubic", **ipargs) @register_interpolator def interpolated_univariate_spline(x: np.ndarray, y: np.ndarray, **ipargs: Dict[str, Any]) -> Callable: """One-dimensional interpolating spline for the given points Uses the scipy.interpolate.InterpolatedUnivariateSpline function behind the scenes. The original only deals with one-dimensional y arrays, so multiple calls are made for higher dimensional y arrays. The dimensions are handled independently of each other. Args: x: 1-dimensional array with original x-values. y: Array with original y-values. ipargs: Keyword arguments passed on to the scipy-interpolator. Returns: Interpolating spline function """ if y.ndim == 1: return scipy.interpolate.InterpolatedUnivariateSpline(x, y, **ipargs) # Loop over columns in y for higher dimensions def _interpolated_univariate_spline(x_new: np.ndarray) -> np.ndarray: """Interpolate using an interpolating spline""" first_y = (slice(len(y)),) first_new = (slice(len(x_new)),) y_new = np.zeros(x_new.shape[:1] + y.shape[1:]) for last_cols in np.ndindex(y.shape[1:]): idx_new = first_new + last_cols idx_y = first_y + last_cols y_new[idx_new] = scipy.interpolate.InterpolatedUnivariateSpline(x, y[idx_y], **ipargs)(x_new) return y_new return _interpolated_univariate_spline @register_interpolator def barycentric_interpolator(x: np.ndarray, y: np.ndarray, **ipargs: Dict[str, Any]) -> Callable: """The interpolating polynomial through the given points Uses the scipy.interpolate.BarycentricInterpolator function behind the scenes. Args: x: 1-dimensional array with original x-values. y: Array with original y-values. ipargs: Keyword arguments passed on to the scipy-interpolator. Returns: Barycentric interpolation function """ return scipy.interpolate.BarycentricInterpolator(x, y, **ipargs) PKLmidgard/math/rotation.pyPKLmidgard/parsers/_parser.pyPKL midgard/parsers/_parser_chain.pyPKLmidgard/parsers/_parser_line.pyPKL midgard/parsers/_parser_sinex.pyPK!H) -8(midgard-0.1.2.dist-info/entry_points.txtN+I/N.,()LIO,J/JIM,NE[&fqqPKNL|SFFmidgard-0.1.2.dist-info/LICENSEThe MIT License (MIT) Copyright (c) 2018 Norwegian Mapping Authority Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK!HNOmidgard-0.1.2.dist-info/WHEEL HM K-*ϳR03rOK-J,/RH,zd&Y)r$[)T&UrPK!H`@K midgard-0.1.2.dist-info/METADATAVMo7W KbhWM FHIJ;u嬖1ܒ\)_VsDo{3FdvvWb)k\@Zz%Wkqֵ ᦋЁ+OAwWc5blb>_XpQAq>^AhZ_^/{Ϋ1. X:ŵdh~Gnɰps-4AȭV{ Y_~y,.0^7X:keį]GV52]j$LA㚚b6X4< AWm>$!-G (}QhK8o6~_]ލGK] fFOF& S׷G»l |жz~˺PCҷ7wWbNei)r+=Ɋ{7^92 l[7'?6b@Bȩ\ m5ɩx]KiS m:AƴVfxùv]A'1 C'f A-m n-.[d'kȅ8=]Sثt!ĝe P6 rlQ8R EX!(l>!(-c$߫6Ɍ~A''Xt1LˀP 27/ƱtΝ_/8D_Bڤ# tݘ|k-htc8@w5w(WȫL#<<F9,W 4CD2 BC]"{4 ̀WV* MvP\ሡ,9 fd_JR q6bz?x'N'C^"bu]pc홦fTDe Z &IQ)7L^w-\}w}7vW4Ho< ICE;ꍒs,-7ӊ6]Y3$WOԀ)#gX`4#nw'k!+uO DLu{ŽQr̀t-*c䝂!H@;FK(:4Ď8oC^ űc\tQhy߻'wPr*ɿmt}pЪ 6Iq Ȕ;eN t+4=>< 3:oM|dyqAzSUc f9щJ0n&p-`)'ʚX_OELMF-WB rm g D=oIq_# PK!HS. midgard-0.1.2.dist-info/RECORDKsJ4<@ j7B@#48*MM"Y}uNGu4 %A0.D47}MF֜Ь]%۶06S"h90DeʶhPF0oQ0vh8{%i~[RSR|퇚uA hY~AO(; 6pg4&[ >eӿǀZro^^,TKqCyW!5ϱ(a%zh4+r-5C&(u6WoΤϲu{{UWHTn|'@5 2s%ZG=8Ą}l7:/wV/#Q ؠo6eEnڱqf7)t0F\UE~KN/MG6EylUzcZ 󧡏n;U`ZY=\UqDNYim+*PƠ xiq6"iP~Y"Q* ] &tΛk_l#AQ$>5_şYu%3DY2a6h:"Ԙǰ#X&KPFhƸǟ[1.(7I68 c\6e'+ + midgard/dev/console.pyPK5L|midgard/dev/exceptions.pyPKuL3"midgard/dev/interactive.pyPK4[L/8<<k"midgard/dev/library.pyPKױL>midgard/dev/log.pyPKLee ?midgard/dev/optional.pyPK᱐LUmidgard/dev/plugins.pyPK豐LUmidgard/dev/profiler.pyPKLVmidgard/dev/timer.pyPKL@Vmidgard/dev/util.pyPKZLnOqVmidgard/files/dates.pyPKƱL\midgard/files/dependencies.pyPKL\midgard/files/files.pyPKL]midgard/math/__init__.pyPKFL i++I]midgard/math/interpolation.pyPKLmidgard/math/rotation.pyPKLԈmidgard/parsers/_parser.pyPKL midgard/parsers/_parser_chain.pyPKLJmidgard/parsers/_parser_line.pyPKL midgard/parsers/_parser_sinex.pyPK!H) -8(ʼnmidgard-0.1.2.dist-info/entry_points.txtPKNL|SFF8midgard-0.1.2.dist-info/LICENSEPK!HNOmidgard-0.1.2.dist-info/WHEELPK!H`@K Dmidgard-0.1.2.dist-info/METADATAPK!HS. ͔midgard-0.1.2.dist-info/RECORDPK$$! \